The Singleton mode limits only one instance for a class, and the object Pool Mode limits the number of class instances. The object pool class is like an object administrator. It stores instances of classes with a limited number of instances in the form of a static list (that is, a pool containing objects, each instance is also marked with a flag indicating whether the instance is occupied. When the class is initialized, the object pool is initialized and the instance is created. Then, you can request an instance from this class. If all instances in the pool are occupied, an exception is thrown. After the user has used up the instance, the user also needs to "return" the instance, that is, release the occupied space. The members of the Object pool class should be static. Users should not be able to access the constructor of objects in the pool to prevent users from bypassing the object pool to create instances. This mode is used for database connection management. For example, the number of connections for each user is limited, so that each connection is an object in a pool, and the "connection pool" class can control the number of connections.
Java object Lifecycle Analysis
Java object lifecycle consists of three phases: Object creation, object usage, and object clearing. Therefore, the lifecycle length of an object can be expressed in the following expression: t = t1 + T2 + T3. T1 indicates the object creation time, T2 indicates the object usage time, and T3 indicates the object clearing time. From this, we can see that only T2 is the real effective time, while T1 and T3 are the overhead of the object itself. Next we will look at the proportion of T1 and t3 in the entire lifecycle of the object.
We know that Java objects are created by constructors. During this process, all constructors in the constructor chain are automatically called. In addition, by default, Java initializes the variable to a definite value when calling the class constructor: all objects are set to null, set integer variables (byte, short, Int, long) to 0, float and double variables to 0.0, and logical values to false. Therefore, the time overhead of using the new keyword to create an object is large, as shown in table 1.
Table 1 Comparison of time-consuming operations
Operation |
Example |
Standardization time |
Local assignment |
I = N |
1.0 |
Instance assignment |
This. I = N |
1.2 |
Method call |
Funct () |
5.9 |
New Object |
New object () |
980 |
Create an array |
New int [10] |
3100 |
From table 1, we can see that it takes 980 units of time to create an object, which is 980 times of the local value assignment time and 166 times of the method call time, however, it takes more time to create an array.
Then let's look at the process of clearing objects. We know that one of the advantages of Java is that Java programmers do not need to explicitly release objects like C/C ++ programmers, but are called garbage collectors) the automatic memory management system automatically recycles the memory occupied by spam objects at a scheduled time or when the memory is insufficient. There are always advantages and disadvantages in everything. Although this provides great convenience for Java programmers, it also brings a large performance overhead. This overhead includes two aspects: first, the object management overhead. GC must monitor the running status of each object in order to release objects correctly, this includes object application, reference, reference, and assignment. Second, when GC starts to recycle "junk" objects, the system will pause the execution of the application, and occupy the CPU alone.
Therefore, to improve the performance of applications, we should minimize the number of times new objects are created. At the same time, we should minimize the time required for T1 and T3, these can be achieved through the object pool technology.
Basic Principles of Object pool technology
The basic principle of Object pool technology has two core points: caching and sharing. For those frequently used objects, they are cached instead of being released immediately after use, for subsequent applications to reuse, thus reducing the number of times objects are created and released, and thus improving the application performance. In fact, because the object pool technology limits the number of objects to a certain extent, it also effectively reduces the application memory overhead.
The basic idea of using the object pool is:
Save the used objects and use them again when you need them for the next time. This reduces the overhead caused by frequent object creation to some extent. Not all objects are suitable for pooling-because maintaining the object pool also causes certain overhead. Pooling objects with low overhead during generation may lead to a situation where the overhead of maintaining the object pool is greater than that of generating new objects, reducing performance. However, for objects with considerable overhead during generation, Pooling technology is an effective strategy to improve performance. The following is an example of building an object pool:
Public class objectpool {private int numobjects = 10; // the size of the Object pool private int maxobjects = 50; // The maximum size of the Object pool private vector objects = NULL; // stores the vector (pooledobject type) of objects in the object pool public objectpool () {}/ *** creates an object pool ***/Public synchronized void createpool () {// make sure the object pool is not created. If the object is created, the object's vector objects will not be empty. If (objects! = NULL) {return; // if the object has been created, return} // creates a vector to save the object. Initially, there are 0 elements objects = new vector (); // create a specified number of objects for (INT x = 0; x <numobjects; X ++) {If (objects. size () = 0) & this. objects. size () <this. maxobjects) {object OBJ = new OBJ (); objects. addelement (New pooledobject (OBJ) ;}} public synchronized object GetObject () {// ensure that the object pool has been created if (Objects = NULL) {return NULL; // if the object pool has not been created, return Null} object conn = getfreeobject (); // obtain an available object // if no object can be used currently, that is, all objects are in use. While (conn = NULL) {Wait (250); Conn = getfreeobject (); // try again until available objects are obtained, if // getfreeobject () returns NULL, it indicates that available objects cannot be obtained after a batch of objects are created} return conn; // return the available objects}/*** this function returns an available object from the objects object in the object pool. If * No available objects exist, create several objects, and put it in the object pool. * If all objects are in use after creation, null */private object getfreeobject () is returned () {// obtain an available object from the object pool object OBJ = findfreeobject (); If (OBJ = NULL) {createobjects (incrementalobjects ); // if there are no available objects in the current Object pool, create some objects // re-query whether there are available objects OBJ = findfreeobject () from the pool (); // if no available object is available after the object is created, null if (OBJ = NULL) {return NULL ;}} return OBJ ;} /*** search for all objects in the object pool and find an available object. * if no available object exists, null */private object findfreeobject () {OB is returned. Ject OBJ = NULL; pooledobject pobj = NULL; // obtain all objects in the object pool vector, enumeration enumerate = objects. elements (); // traverse all objects to see if there are available objects while (enumerate. hasmoreelements () {pobj = (pooledobject) enumerate. nextelement (); // if this object is not busy, obtain its object and set it as busy if (! Pobj. isbusy () {OBJ = pobj. getObject (); pobj. setbusy (true);} return OBJ; // return the available objects found}/*** this function returns an object to the object pool and sets this object to idle. * All objects obtained using the object pool should be returned if this object is not used. */Public void returnobject (Object OBJ) {// ensure that the object pool exists. if the object is not created (does not exist), return if (Objects = NULL) {return;} directly ;} pooledobject pobj = NULL; enumeration enumerate = objects. elements (); // traverses all objects in the object pool and finds the object to be returned while (enumerate. hasmoreelements () {pobj = (pooledobject) enumerate. nextelement (); // first find the object to be returned in the object pool if (OBJ = pobj. getObject () {// found. Set this object to idle pobj. setbusy (false); break ;}}/*** off Close all objects in the object pool and clear the object pool. */Public synchronized void closeobjectpool () {// ensure that the object pool exists. If it does not exist, return if (Objects = NULL) {return;} pooledobject pobj = NULL; enumeration enumerate = objects. elements (); While (enumerate. hasmoreelements () {pobj = (pooledobject) enumerate. nextelement (); // If busy, wait for 5 seconds if (pobj. isbusy () {Wait (5000); // wait for 5 seconds} // delete it from the object pool vector objects. removeelement (pobj);} // set the object pool to null objects = NULL;}/*** to wait for the program to wait for the specified Millisecond count */private void wait (INT mseconds) {try {thread. sleep (mseconds);} catch (interruptedexception e) {}}/*** class used internally to save objects in the object pool. * This class has two members, one being an object, and the other being a flag indicating whether the object is in use. */Class pooledobject {object objection = NULL; // Boolean busy = false; // indicates whether the object is in use. No constructor is in use by default, create a pooledobject object public pooledobject (Object objection) {This. objection = objection;} // return the object public object GetObject () {return objection;} // set the object public void setobject (Object objection) {This. objection = objection;} // get whether the object is busy with public Boolean isbusy () {return busy;} // set the object to public void setbusy (Boolean busy) {This. busy = busy ;}} test class: Code: public class objectpooltest {public static void main (string [] ARGs) throws exception {objectpool objpool = new objectpool (); objpool. createpool (); object OBJ = objpool. getObject (); returnobject (OBJ); objpool. closeobjectpool ();}}
Commons-Pool provides a set of useful object pool components. It is easy to use, but it is unnecessary to use the object pool for some simple objects.
Objectpool defines a simple pooled interface with three corresponding implementations.
Genericobjectpool: Implements configurable first-in-first-out or first-in-first-out (LIFO/FIFO) actions. By default, it is used as a first-in-first-out queue. This means that when there are available idle objects in the object pool, borrowobject returns the nearest object instance. If the LIFO attribute is set to false, the object instance is returned according to the FIFO action.
Stackobjectpool: implements the LIFO action.
Softreferenceobjectpool: implements the last-in-first-out (LIFO) behavior. In addition, the object pool saves each object reference in softreference, allowing the Garbage Collector to recycle objects for memory.
The keyedobjectpool defines an interface for accessing objects with any key (which can be pooled to objects). There are two corresponding implementations.
Generickeyedobjectpool: Implements first-in-first-out (FIFO) behavior.
Stackkeyedobjectpool: implements the last-in-first-out (LIFO) behavior.
Poolableobjectfactory defines the life cycle method of pooled objects. We can use it to separate the creation, persistence, and destruction of pooled and managed objects.
Basepoolableobjectfactory is an abstract class implementing the poolableobjectfactory interface. We can extend it to implement our own pooled factory.
A simple example of using an object pool:
Package TF; import Org. apache. commons. pool. basepoolableobjectfactory; import Org. apache. commons. pool. objectpool; import Org. apache. commons. pool. impl. stackobjectpool; public class pool {public static void main (string [] ARGs) throws exception {objectpool pool = new stackobjectpool (New userfactory (); User u = (User) pool. borrowobject (); // borrow an object u from the pool. setname ("me"); U. sayhello (); pool. returnobject (U); // return object} static class userfactory extends basepoolableobjectfactory {/*** generate a new object */public object makeobject () {return new user ();} /*** restore object status */Public void passivateobject (Object OBJ) {user u = (User) OBJ; U. clear () ;}} static class user {string name; void setname (string name) {This. name = Name;} void sayhello () {system. out. println ("hello," + name);} void clear () {name = "";}}}
Reprint please indicate the source http://blog.csdn.net/shimiso
Welcome to our technical exchange group: 173711587