オブジェクトプーリング
commons-poolを利用してDBではなく
自作クラスのオブジェクトをプーリングしたい場合には
下記のようにクラスを作成すれば実現できる。
Factoryクラス
/**
*
*/
package main2.pool.factory;import main2.pool.PooledObject;
import org.apache.commons.pool.PoolableObjectFactory;
/**
* プールされているオブジェクトに対するアクションを実行するクラス
* 2011/09/03
* PoolFactory.java
*/
public class PoolFactory implements PoolableObjectFactory{/**
* プールするオブジェクトを作成する
* {@inheritDoc}
*/
public Object makeObject() throws Exception {
System.out.println("Call makeObject.");
// プールするオブジェクトのインスタンス生成
return new PooledObject();
}/**
* オブジェクトを破棄する
* {@inheritDoc}
*/
public void destroyObject(Object obj) throws Exception {
System.out.println("Call destroyObject.");}
/**
* オブジェクトを検証する
* このインスタンスがプールにて安全に使用できるかを判断します。 このオブジェクトを破棄するべき場合には false
* {@inheritDoc}
*/
public boolean validateObject(Object obj) {
System.out.println("Call validateObject.");return true;
}/**
* オブジェクトを再初期化する
* {@inheritDoc}
*/
public void activateObject(Object obj) throws Exception {
System.out.println("Call activateObject.");}
/**
* プールに戻されたインスタンスの後処理
* {@inheritDoc}
*/
public void passivateObject(Object obj) throws Exception {
System.out.println("Call passivateObject.");}
}
プーリングに対する操作クラス
/**
*
*/
package main2.pool.controller;import java.util.NoSuchElementException;
import main2.pool.factory.PoolFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.apache.commons.pool.impl.GenericObjectPoolFactory;/**
* 2011/09/03
* PoolingController.java
*/
public class PoolingController<E> {private ObjectPool pool;
/**
* コンストラクタ
* プーリングオブジェクトの生成と、パラメータの設定処理。
*/
public PoolingController() {
System.out.println("constractor PoolingController - start");/**
* パターン1
* GenericObjectPoolFactoryのコンストラクタでパラメータ設定
*/
// コンストラクタ
// GenericObjectPoolFactory(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle)
GenericObjectPoolFactory factory = new GenericObjectPoolFactory(new PoolFactory(),1);
pool = factory.createPool();/**
* パターン2
* GenericObjectPoolでパラメータ設定
*/
this.pool = new GenericObjectPool(new PoolFactory());// 同時にプールから取り出すことのできるオブジェクトの最大数
((GenericObjectPool) pool).setMaxActive(2);//プール内に保持できる未使用のオブジェクトの最大数
((GenericObjectPool) pool).setMaxIdle(2);// プール内に存在可能なアイドル接続数の最大数を指定
// 接続切断時、DBCPはこの接続をプール内に溜めようとしますが
// その時プール内にこの数以上の接続が存在した場合、接続は溜められず削除
((GenericObjectPool) pool).setMinIdle(10);// 接続要求があったときに利用できる接続が存在しない(つまり接続数がmaxActiveに達している)場合
// 利用できるようになるまで待つ時間をミリ秒単位で指定
((GenericObjectPool) pool).setMaxWait(6000);// borrowObject() メソッドは新たなオブジェクトが利用できるまでまたは 最大待機時間 に達するまで待機
((GenericObjectPool) pool).setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);/**
* パターン3
* GenericObjectPoolでパラメータ設定(専用のconfigクラス利用)
*/
Config poolsConfig = new Config();
poolsConfig.maxActive = 2;
poolsConfig.maxIdle = 3;
poolsConfig.maxWait = 6000;
poolsConfig.minIdle = 2;
poolsConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;this.pool = new GenericObjectPool(new PoolFactory(), poolsConfig);
// borrowObject()する前にPoolFactoryクラスのvalidateObject()を実施しバリデートチェックする
((GenericObjectPool) pool).setTestOnBorrow(false);// 下記setTestOnReturn()がtrueだとaddObject()がコールされた際にPoolFactoryクラスのvalidateObjectを実施する
// returnObject()する前にvalidateチェックする
((GenericObjectPool) pool).setTestOnReturn(true);System.out.println("constractor PoolingController - end");
}
/**
* プールから取り出す
* もしオブジェクトがプールされていなければ
* ファクトリのmakeObject()によりオブジェクトが生成される。
* 生成する際にmaxActive、maxIdleなどの数値により生成するかどうか変わる。
* オブジェクトを返却する際にvalidateするかはコンストラクタでおこなっているset~()
* のboolean値により変わる
* @return プールされているオブジェト
*/
public E borrowObject() {
try {
return (E) pool.borrowObject();
} catch(NoSuchElementException e) {
System.out.println("timeout");
//e.printStackTrace();
throw new RuntimeException(e);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}/**
* プールに返却する
* @param obj
*/
public void returnObject(Object obj) {
try {
pool.returnObject(obj);
} catch (Exception e) {
e.printStackTrace();
}
}/**
* プールにオブジェクトを追加する
*/
public void addObject() {
try {
pool.addObject();
} catch (Exception e) {
e.printStackTrace();
}
}/**
* 現在プールから貸し出されているインスタンスの数
*/
public int getNumActive() {
return pool.getNumActive();
}/**
* 現在プール内にある使用されていないインスタンスの数
*/
public int getNumIdle() {
return pool.getNumIdle();
}/**
* プールのクリア
*/
public void clear() {
try {
pool.clear();
} catch (Exception e) {
e.printStackTrace();
}
}/**
* プールのクローズ
*/
public void close() {
try {
pool.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
呼び出すサンプル
PoolingControllersample = new PoolingController ();
System.out.println("1. borrowObject");// コントローラからプールされているオブジェクトを取得
Object obj = sample.borrowObject();
System.out.println(obj);
// 現在プールされているオブジェクト数を標準出力
System.out.println("Idle : " + sample.getNumIdle());System.out.println("addObject");
// プールするオブジェクトの生成とプーリング
sample.addObject();
System.out.println("Idle : " + sample.getNumIdle());System.out.println("addObject");
sample.addObject();
System.out.println("Idle : " + sample.getNumIdle());
sample.clear();
sample.close();