Developing a universal object pool architecture in Java can better utilize resources and can minimize the cost of initialization. --By karthik rangaraju
Most people are familiar with the use of the object pool directly or indirectly to connect a database. But usually you can also place objects into the object pool to save important resources, improve program efficiency and control access to incapable resources. For design, cost or performance, the objects in the object cell is usually limited. They or initializes costs, or fewer objects. Using the object pool, we can manage the competitive client access to a limited object set.
Sun's Java HotSpot Technology Development Technical Development Technical Development Technical Development Group recommends that Java programmers do not use their own objects. Alternatively, it recommends that they are allocated with improved memory management and object assignments in Java Virtual Machine (JVM). Although HotSpot is more efficient than the previous JVMS, it is more effective in administrative objects, but it does not enable the creation of objects that are based on resources other than JVMs to achieve optimal. So, although the performance of HotSpot has improved, you can still benefit from the object pool.
The object pool is mainly to better use your resources. For example, it is envisaged that there are considerable customers to effectively use few databases or network connections. You can release resources by limiting access to objects (you can access objects only when you need it), you can release resources to use other clients. Using the object pool to improve the utilization of the object can usually improve system performance.
You can use the object pool to minimize the cost of initialization. Typical examples include databases, network connections, and threads. Such connections typically require a lot of time to initialize. Once these connections are created, you can reuse them, thereby saving costs. Therefore, you can place an object that is highly cost-effective (considered from time, memory, or other resource) into the object pool. For example, most containers put Enterprise JavaBeans into the object pool to avoid duplicate resource allocation and status initialization.
Let us consider a universal object pool architecture that can accommodate any Java objects. This architecture contains a primary PoolManager class that allows us to access objects in the object pool. By calling poolManager.get (), you can get an object, the method reads the object from the object pool, encapsulates it in a PooledResource container object and returns a reference to the container. You can return the object to the object pool by calling PooledResource.release (). In order to make PoolManager can be extended, I use the Strategy design mode (see Design Patterns: Elements of Reusable Object-Oriented Software book), which allows the application to define object creation and object pool capacity management policies. The ObjectManager class is the key to implementation: the application must extend ObjectManager, providing creation logic to place objects into the target pool, and provide a policy to increase or reduce the capacity of the object pool, and can also regularly refresh the target pool. Object.
PoolManager provides a constructor for different object pool capacity management strategies (see List 1). Build a PoolManager list 1. PoolManager class allows us to access objects in the object pool and provide a constructor for different object pool capacity management policies.
/ **
* Constructs a new poolmanager with the specified
* ObjectManager and specified initial size.
* @Param PManager Reference to ObjectManager to be used. * @Param PMaxSize Max Size Of Pool (Once this Limit IS
* Reached, Additional Requests Result in
* ObjectManager.incReasePoolsize () Being called.
* @Param PinitialSize Number of Objects to Add to the THE
* pool immediately. The Objects Are Obtained by Calling
* ObjectManager.getneWObject ().
* @see ObjectManager # increasepoolsize (int)
* @see objectManager # getNewObject ()
* /
Public PoolManager (ObjectManager PManager,
Int pmaxsize,
INT Pinitialsize)
/ **
* Constructs a pool with Zero Initial Size
* @Param PManager Reference To ObjectManager to BE
* USED.
* @Param PMaxSize Max Size Of Pool (Once this Limit)
* Is Reached, Additional Requests Result in
* ObjectManager.incReasePoolsize () Being called.
* @see #PoolManager (ObjectManager, int, int, int)
* @see ObjectManager # increasepoolsize (int)
* /
Public PoolManager (ObjectManager PManager,
INT PMAXSIZE)
/ **
* Construct a pool with zerio max and initial size.
* This Lets ObjectManager.IncreasePoolsize () Dictate
* The pool sizing policy.
* @Param PManager Reference To ObjectManager to BE USED
* @see #PoolManager (ObjectManager, int, int, int)
* /
Public poolmanager (ObjectManager PManager)
When PoolManager is built with initial, maximum capacity, it calls ObjectManager.create () to create an initial object set. When the client requests an object and its initial set is over, the capacity of the object pool will increase until the maximum is reached. At this time, new requests will call ObjectManager.inCreasePoolSize (). As long as INCREASEPOOLSIZE () is not covered, the request will be blocked until an object is released back to the object pool.
By determining the maximum capacity to build PoolManager causes Lazy Initialization, this means that the object is created when the object is requested, and then the object is kept in the object pool. When the POOLMANAGER is not built without the initial or maximum capacity, execute ObjectManager.inCreasePoolSize () can specify the capacity of the object pool - because when the object pool is empty, it is called from poolmanager.get () (see List 2). Read object list 2. PoolManager.get () Read objects from the object pool and create a new object as needed and increase the capacity of the object pool. / **
* Retrieves a pooledObject from the pool.
* @Return Reference to PooledObject Obtained from Thae
* pool.
* @Throws InterruptedException if the thread is
* Interrupted When Waiting.
* @Throws PoolDisableDexception if disable () IS Called
* While the thread is waiting.
* /
Public PooledObject Get () Throws PoolDisableDexception,
InterruptedException
{
PooledObject Resource = NULL;
SYNCHRONIZED (this)
{
IF (meNabled == false)
{
Throw new PoolDisableDexception
("Pool disabled");
}
// mwaitcount is buy to keep track of total
// Requests blockd.
MWAITCOUNT ;
IF (MPool.isempty () && mcurrentsize { Add (MobjectManager.create ()); McURRENTSIZE ; } Else if (MPool.Isempty ()) { MOBJECTMANAGER.INCREASEPOOLSIZE (MWAITCOUNT); } While (menabled && mpool.isempty ()) { Try { THIS.WAIT (); } Catch (InterruptedException E) { MWAITCOUNT -; Throw e; } } MWAITCOUNT -; IF (Menable) { Resource = (pooledObject) mpool.dequeue (); } Else { Throw new PoolDisableDexception ("Pool disabled"); } } Mreamquire (resource.get ()); Return resource; } The poolmanager.get () method also passes the unfinished request quantity to ObjectManager.inCreasePoolSize () so you can delay the creation of new objects until you reach a specific limit. This facilitates the implementation of complex object pool capacity strategies. The poolmanager.get () method checks if the object pool is activated and increases the number of requests waiting for implementation. It also views whether the object pool is empty. If there is a space to increase the object pool, it calls ObjectManager.create () to create a new object, add it to the object pool and returns to the caller. Otherwise, it calls ObjectManager's increagePoolSize (), incoming number of requests. If the object pool is still empty - because ObjectManager.inCreasePoolSize () does not create a new object - request will be blocked until an object is released back to the object pool. PoolManager regularly calls ObjectManager.DecreasePoolSize () to see if the objects that are not used in the object pool can be reclaimed. You can override the getDecrementInterVal () method to change the default 30 minutes of time interval. When executing DecreasePoolSize (), the request to get or release the object is blocked. In addition, DecReasePoolSize () can call the ShrinkPool () method, which allows an object to remove the object pool and provide reference to it. PoolManager also allows you to refresh objects in the object pool - for example, make sure the TCP / IP connection is not timeout. POOLManager is regular (default, every five minutes) calls ObjectManager.refresh (), incoming an item, providing read-only access to the object. When executing ObjectManager.Refresh (), a request to get or release the object from the object pool will be blocked. Finally, PoolManager provides hooks (via poolreleasestrategy), which can process objects in the object pool before the client gets an object. This provides us with convenience, allowing us to reset them in front of the object before they return to the object pool - handle them. For example, you can view the database transaction isolation level (isolation level) or reset an error code. The object pool architecture we describe here is universal, which is suitable for different applications. Allows you to control the capacity of the object pool, object fill strategy, and object status. A well-designed object pool can greatly improve your application efficiency, regardless of consideration from speed, or from resource utilization, this architecture can provide such benefits.