If you are looking for a quick implementation of an object pool, then look no further than the excellent Apache Commons Pool2 implementation. Pool2 is far better and faster than the original commons pool library.
Object pool can be used to cache those objects that are expensive to setup and cannot be created for every request or thread - e.g. DB connections, MQTT broker connections, AMQP broker connections, etc.
The following code snippets would show you how simple it is to create a pool for your 'expensive-to-create' objects.
Object pool can be used to cache those objects that are expensive to setup and cannot be created for every request or thread - e.g. DB connections, MQTT broker connections, AMQP broker connections, etc.
The following code snippets would show you how simple it is to create a pool for your 'expensive-to-create' objects.
Any object pool typically requires 2 parameters [GenericObjectPool.java] ---
1) A factory object to handle creation and destruction of your objects [MyObjectFactory.java]
2) A configuration object to configure your pool. [GenericObjectPoolConfig,java]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.pool2.BasePooledObjectFactory; | |
import org.apache.commons.pool2.PooledObject; | |
import org.apache.commons.pool2.impl.DefaultPooledObject; | |
public class MyObjectFactory | |
extends BasePooledObjectFactory<MyObject> { | |
@Override | |
public MyObject create() { | |
//Put in your logic for creating your expensive object - e.g. JDBC Connection, MQTT Connection, etc. | |
//here for the sake of simplicity, we return a custom pooled object of a custom class called MyObject. | |
return new MyObject(); | |
} | |
/** | |
* Use the default PooledObject implementation. This helps in acting like a proxy for doing extra operations. | |
* Please read API docs of DefaultPooledObject for more information | |
*/ | |
@Override | |
public PooledObject<MyObject> wrap(MyObject myObject) { | |
return new DefaultPooledObject<MyObject>(myObject); | |
} | |
@Override | |
public void destroyObject(PooledObject<MyObject> p) { | |
//Destroys an instance no longer needed by the pool. | |
//Please put in your scavenging logic here...closing socket connections, mqtt broker connections, etc. | |
System.out.println("destroying"); | |
} | |
// for all other methods, the no-op implementation | |
// in BasePooledObjectFactory will suffice | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.pool2.impl.GenericObjectPool; | |
import org.apache.commons.pool2.ObjectPool; | |
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; | |
public class PoolDemo | |
{ | |
public static void main(String[] args) throws Exception | |
{ | |
//Create the Object pool. | |
ObjectPool pool = initializePool(); | |
Object obj = null; | |
try { | |
obj = pool.borrowObject(); | |
try { | |
//...use the object... | |
} catch(Exception e) { | |
// invalidate the object | |
pool.invalidateObject(obj); | |
// do not return the object to the pool twice | |
obj = null; | |
} finally { | |
// make sure the object is returned to the pool | |
if(null != obj) { | |
pool.returnObject(obj); | |
} | |
} | |
} catch(Exception e) { | |
// failed to borrow an object | |
} | |
} | |
//A helper method to initialize the pool using the config and object-factory. | |
public ObjectPool initializePool() throws Exception | |
{ | |
// We confugure the pool using a GenericObjectPoolConfig | |
//Note: In the default implementation of Object Pool, objects are not created at start-up, but rather are created whenever the first call | |
//to the pool.borrowObject() is made. This object is then cached for future use. | |
//It is recommended to put these settings in a properties file. | |
GenericObjectPoolConfig config = new GenericObjectPoolConfig(); | |
config.setMaxTotal(3); | |
config.setBlockWhenExhausted(true); | |
config.setMaxWaitMillis(30 * 1000); | |
//We use the GenericObjectPool implementation of Object Pool as this suffices for most needs. | |
//When we create the object pool, we need to pass the Object Factory class that would be responsible for creating the objects. | |
//Also pass the config to the pool while creation. | |
ObjectPool pool = new GenericObjectPool<MyObject>(new MyObjectFactory(), config); | |
return pool; | |
} | |
} |
No comments:
Post a Comment