Implementation of General Object pool
Object pool construction and management can be achieved in multiple ways. The most flexible way is to specify the class type of the pooled object outside the object pool, that is, when the objectpoolfactory class creates an object pool, it dynamically specifies the class type of the object pooled by the object pool, the implementation code is as follows:
... Public objectpool createpool (parameterobject paraobj, class clstype ){ Return new objectpool (paraobj, clstype ); } ... |
The paraobj parameter is used to specify the feature attribute of the Object pool, And the clstype parameter specifies the type of the object stored in the object pool. After an object pool is created, we use it to manage objects. The specific implementation is as follows:
Public class objectpool { Private parameterobject paraobj; // attribute parameter object of the Object pool Private class clstype; // type of the objects stored in the object pool Private int currentnum = 0; // number of currently created objects in the object pool Private object currentobj; // the objects that can be lent out by the object pool. Private vector pool; // The pool used to store objects Public objectpool (parameterobject paraobj, class clstype ){ This. paraobj = paraobj; This. clstype = clstype; Pool = new vector (); } Public object GetObject (){ If (pool. Size () <= paraobj. getmincount ()){ If (currentnum <= paraobj. getmaxcount ()){ // If no objects are available in the current pool and the number of created objects is smaller than the maximum value // Poolobjectfactory creates a new object Poolableobjectfactory objfactory = poolableobjectfactory. getinstance (); Currentobj = objfactory. Create object (clstype ); Currentnum ++; } Else { // If no objects are available in the current pool and the maximum number of created objects has been reached, // You can only wait for other threads to return objects to the pool. Synchronized (this ){ Try { Wait (); } Catch (interruptedexception e ){ System. Out. println (E. getmessage ()); E. printstacktrace (); } Currentobj = pool. firstelement (); } } } Else { // If there are available objects in the current pool, the objects are taken directly from the pool. Currentobj = pool. firstelement (); } Return currentobj; } Public void returnobject (Object OBJ ){ // Ensure that the object has the correct type If (obj. isinstance (clstype )){ Pool. addelement (OBJ ); Synchronized (this ){ Policyall (); } } Else { Throw new illegalargumentexception ("the object pool cannot store the specified object type "); } } } |
From the code above, we can see that objectpool uses a java. util. vector is an extensible Object pool, and its constructor is used to specify the class type of the pooled object and some attributes of the Object pool. When an object is returned to the object pool, it checks whether the object type is correct. When no available objects exist in the object pool, it waits for the pooled objects that have been used to return to the pool, or creates a new object instance. However, the creation of new object instances is not in the objectpool class, but by the Createobject method of the poolableobjectfactory class. The specific implementation is as follows:
... Public object Createobject (class clstype ){ Object OBJ = NULL; Try { OBJ = clstype. newinstance (); } Catch (exception e ){ E. printstacktrace (); } Return OBJ; } ... |
In this way, even if the implementation of the general object pool is complete, let's take a look at how the client uses it, assuming that the class type of the pooled object is stringbuffer:
... // Create an object pool Factory Objectpoolfactory poolfactory = objectpoolfactory. getinstance (); // Define the attributes of the created Object pool Parameterobject paraobj = new parameterobject (2, 1 ); // Use the object pool factory to create an object pool for storing stringbuffer objects Objectpool pool = poolfactory. createpool (paraobj, string buffer. Class ); // Retrieve a stringbuffer object from the pool Stringbuffer buffer = (stringbuffer) pool. GetObject (); // Use the stringbuffer object retrieved from the pool Buffer. append ("hello "); System. Out. println (buffer. tostring ()); ... |
It can be seen that the general object pool is very convenient to use, not only can avoid the overhead of frequent object creation, but also a high degree of universality. However, it is a pity that a large number of cast operations and some synchronization operations on the vector class are required to improve the performance in some situations, especially for objects with short creation periods.