(2) Object pool

Source: Internet
Author: User

The object pool is relatively simple. The concept is to repeat idle stateless components to avoid repeated release/creation, and the implementation is relatively simple. Just use a tlist, note the following two problems:

1. For thread synchronization, the service must be multi-threaded (and processes can be used to replace threads). tcriticalsection or other protection should be used to access tlist;

2. The size of the Object pool should be set to a size limit, that is, the pool does not need to put too many idle elements (after all, it occupies memory); the total number of objects (idle and busy) there should also be a limit on the number of items. Otherwise, the memory may be insufficient. When the number is full, if there are no idle items, wait until there are items idle (semaphores can be used for processing ).

The thread pool is the same.

I think no matter whether the object pool or the thread pool is not for efficiency, it takes much less time to create the object/thread than to execute your business functions, the pool is used to protect limited resources from being exhausted. You can set the pool size to control resource usage. Otherwise, the system will reject services or crash due to insufficient resources.

// Service component pool, including idle and busy components <br/> tservicepool = Class <br/> private <br/> fpool: tstringlist; <br/> fcritical: tcriticalsection; <br/> fdestroying: Boolean; <br/> fchecktimer: ttimer; <br/> protected <br/> procedure lock; <br/> procedure unlock; <br/> procedure restore (aserviceobject: tcustomserviceobject); <br/> procedure restore (aservice: tserviceclass); <br/> procedure checkserviceobjectstatus (const aserviceobject: tcustomserviceobject; <br/> const AStatus: tserviceobjectstatus); <br/> // check the timeout call. The timeout call is forcibly stopped. <br/> procedure checkservicetimeout (Sender: tobject ); <br/> Public <br/> constructor create; virtual; <br/> destructor destroy; override; <br/> procedure destroyidleobjects; virtual; <br/> procedure clear; <br/> // find an idle element <br/> function POP (const aservicename: string; const aserviceobjectstub: integer =-1): tcustomserviceobject; <br/> // set the component to idle <br/> procedure push (aserviceobject: tcustomserviceobject); <br/> function getidleobjectcount (aservicename: string): integer; <br/> function getbusyobjectcount (aservicename: string): integer; <br/> // recycle reuse element <br/> procedure cycleserviceobject (aserviceobject: tcustomserviceobject ); </P> <p> procedure wmapplicationready (var msg: tmessage); message wm_applicationready; <br/> procedure wmlogout (var msg: tmessage); message wm_logout; <br/> end; <br/>

Function tservicepool. pop (const aservicename: string; <br/> const aserviceobjectstub: integer =-1): tcustomserviceobject; <br/> var <br/> I, index: integer; <br/> alist: tserviceobjectlist; <br/> aobject: tcustomserviceobject; <br/> begin <br/> result: = nil; <br/> lock; <br/> try <br/> // No elements <br/> if not fpool. find (aservicename, index) Then <br/> begin <br/> alist: = tserviceobjectlist. create (aservicename); <br/> fpool. insertobject (index, aservicename, alist); <br/> end <br/> else <br/> alist: = tserviceobjectlist (fpool. objects [Index]); </P> <p> aobject: = nil; <br/> // find the stub element <br/> If aserviceobjectstub> 0 then <br/> begin <br/> for I: = 0 to alist. count-1 do <br/> begin <br/> If INTEGER (tcustomserviceobject (alist [I]) = aserviceobjectstub then <br/> begin <br/> aobject: = tcustomserviceobject (alist [I]); <br/> break; <br/> end; <br/> If aobject = nil then <br/> raise exception. createfmt (s_stubnotfound, [inttostr (aserviceobjectstub)]) <br/> else if aobject. status = osbusy then <br/> raise exception. createfmt (s_stubisbusy, [inttostr (aserviceobjectstub)]); <br/> end <br/> else <br/> begin <br/> // controls the number of elements in the pool (reduce a semaphore, wait for an idle component or obtain the signal of the newly created component) <br/> // unlock first, otherwise it may be deadlocked <br/> unlock; <br/> try <br/> alist. waitfor; <br/> finally <br/> lock; <br/> end; <br/> // find an unlocked idle element <br/> for I: = alist. count-1 downto 0 DO <br/> begin <br/> if not tcustomserviceobject (alist [I]). fislocked and (tcustomserviceobject (alist [I]). status = osidle) Then <br/> begin <br/> aobject: = tcustomserviceobject (alist [I]); <br/> break; <br/> end; <br/> end; <br/> // set the status of the component. <br/> If aobject <> nil then <br/> begin <br/> result: = aobject; <br/> If aobject. status = osidle then <br/> begin <br/> Dec (alist. fidlecount); <br/> Inc (alist. fbusycount); <br/> end; <br/> aobject. status: = osbusy; <br/> end; <br/> finally <br/> unlock; <br/> end; </P> <p> If result <> nil then <br/> begin <br/> If servicelog <> nil then servicelog. serviceobjectpoolpoped (aservicename); <br/> end; </P> <p> procedure tservicepool. push (aserviceobject: tcustomserviceobject); <br/> begin <br/> checkserviceobjectstatus (aserviceobject, osidle); <br/> aserviceobject. fdataobject: = nil; <br/> end; <br/> procedure tservicepool. checkserviceobjectstatus (const aserviceobject: tcustomserviceobject; <br/> const AStatus: tserviceobjectstatus); <br/> var <br/> I, index: integer; <br/> alist: tserviceobjectlist; <br/> aobject: tcustomserviceobject; <br/> vfoundobject: Boolean; <br/> begin <br/> lock; <br/> try <br/> aobject: = nil; <br/> vfoundobject: = false; <br/> if not fpool. find (aserviceobject. fservicename, index) Then <br/> begin <br/> alist: = tserviceobjectlist. create (aserviceobject. fservicename); <br/> fpool. insertobject (index, aserviceobject. fservicename, alist); <br/> end <br/> else <br/> begin <br/> alist: = tserviceobjectlist (fpool. objects [Index]); <br/> for I: = 0 to alist. count-1 do <br/> begin <br/> If tcustomserviceobject (alist [I]) = aserviceobject then <br/> begin <br/> aobject: = tcustomserviceobject (alist [I]); <br/> vfoundobject: = true; <br/> break; <br/> end; <br/> end; </P> <p> If aobject = nil then <br/> begin <br/> aobject: = aserviceobject; <br/> alist. add (aobject); <br/> end; </P> <p> // restore quantity <br/> If vfoundobject then <br/> begin <br/> case aobject. status of <br/> osbusy: <br/> begin <br/> Dec (alist. fbusycount); <br/> // No need to judge whether the lock is required <br/> If (AStatus = osidle) then <br/> begin <br/> // Add a semaphore <br/> alist. signal; <br/> end; <br/> osidle: <br/> begin <br/> Dec (alist. fidlecount); <br/> end; </P> <p> case AStatus of <br/> osbusy: <br/> Inc (alist. fbusycount); <br/> osidle: <br/> Inc (alist. fidlecount); <br/> end; </P> <p> aobject. status: = AStatus; <br/> finally <br/> unlock; <br/> end; <br/> If servicelog <> nil then <br/> servicelog. serviceobjectpoolpushed (aserviceobject. fservicename); <br/> end;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.