1.對象池化技術的基本思路
將用過的對象保存起來,等下一次需要這種對象的時候,再拿出來重復使用,從而在一定程度上減少頻繁創建對象所造成的開銷。用于充當保存對象的“容器”的對象,被稱為“對象池”(Object Pool,或簡稱Pool)。
2. Jakarta Commons Pool組件及其使用
Jakarta Commons Pool是一個用于在Java程序中實現對象池化的組件,它包含兩個包(org.apache.commons.pool和org.apache.commons.pool.impl)。下載commons-dbcp,將commons-pool.jar和commons-collections.jar及commons-dbcp-1.2.2.jar放到所在工程的classpath中。
3. 對象池化的工作中用到的三類對象
l PoolableObjectFactory用于管理被池化的對象的產生、激活、掛起、校驗和銷毀;
l ObjectPool用于管理要被池化的對象的借出和歸還,并通知PoolableObjectFactory完成相應的工作;
l ObjectPoolFactory則用于大量生成相同類型和設置的ObjectPool。
3.1 創立PoolableObjectFactory
PoolableObjectFactory是在org.apache.commons.pool包中定義的一個接口。實際使用的時候需要利用這個接口的一個具體實現。如下:
創建一個實現類PoolableObjectFactorySample.java
import org.apache.commons.pool.PoolableObjectFactory;
public class PoolableObjectFactorySample
implements PoolableObjectFactory {
private static int counter = 0;
/* *
*這個方法用于在必要時產生新的對象。
*/
public Object makeObject() throws Exception {
Object obj = String.valueOf(counter++);
System.err.println("Making Object " + obj);
return obj;
}
/* *
* 這個方法用于將對象“激活”設置為適合開始使用的狀態。
*/
public void activateObject(Object obj) throws Exception {
System.err.println("Activating Object " + obj);
}
/* *
*這個方法用于將對象“掛起”設置為適合開始休眠的狀態。
*/
public void passivateObject(Object obj) throws Exception {
System.err.println("Passivating Object " + obj);
}
/* *
*這個方法用于校驗一個具體的對象是否仍然有效,已失效的對象會被自動交
*給destroyObject方法銷毀
*/
public boolean validateObject(Object obj) {
/* 以1/2的概率將對象判定為失效 */
boolean result = (Math.random() > 0.5);
System.err.println("Validating Object "
+ obj + " : " + result);
return result;
}
/* *
*這個方法用于銷毀被validateObject判定為已失效的對象。
*/
public void destroyObject(Object obj) throws Exception {
System.err.println("Destroying Object " + obj);
}
}
3.2 使用ObjectPool
ObjectPool是在org.apache.commons.pool包中定義的一個接口,實際使用的時候也需要利用這個接口的一個具體實現。如下:
創建一個ObjectPoolSample.java類:
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.StackObjectPool;
public class ObjectPoolSample {
public static void main(String[] args) {
Object obj = null;
/*生成PoolableObjectFactory類的實例*/
PoolableObjectFactory factory = new PoolableObjectFactorySample();
/*生成一個實現了ObjectPool接口的類(例如StackObjectPool)的實例*/
ObjectPool pool = new StackObjectPool(factory);
try {
for(long i = 0; i < 100 ; i++) {
System.out.println("== " + i + " ==");
obj = pool.borrowObject(); //從對象池中取出對象
System.out.println(obj);
pool.returnObject(obj); //將對象放回對象池
}
obj = null;//明確地設為null,作為對象已歸還的標志
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try{
if (obj != null) {//避免將一個對象歸還兩次
pool.returnObject(obj);
}
pool.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
3.3 利用ObjectPoolFactory
要在多處生成類型和設置都相同的ObjectPool就要使用ObjectPoolFactory。ObjectPoolFactory是一個在org.apache.commons.pool中定義的接口,它定義了一個ObjectPool createPool()方法,可以用于大量生產類型和設置都相同的ObjectPool。實例如下:
創建一個ObjectPoolFactorySample.java文件。
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.ObjectPoolFactory;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.StackObjectPoolFactory;
public class ObjectPoolFactorySample {
public static void main(String[] args) {
Object obj = null;
PoolableObjectFactory factory
= new PoolableObjectFactorySample();
ObjectPoolFactory poolFactory
= new StackObjectPoolFactory(factory);
ObjectPool pool = poolFactory.createPool();
try {
for(long i = 0; i < 100 ; i++) {
System.out.println("== " + i + " ==");
obj = pool.borrowObject();
System.out.println(obj);
pool.returnObject(obj);
}
obj = null;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try{
if (obj != null) {
pool.returnObject(obj);
}
pool.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
4.借助BasePoolableObjectFactory
BasePoolableObjectFactory是org.apache.commons.pool包中的一個抽象類。它實現了PoolableObjectFactory接口,并且為makeObject方法提供了一個基本的實現,而activateObject、passivateObject和destroyObject方法不進行任何操作, validateObject始終返回true。通過繼承這個類,而不是直接實現PoolableObjectFactory接口,就可以免去編寫一些只起到讓編譯通過的作用的代碼的麻煩了。實例如下:
創建一個BasePoolableObjectFactorySample.java 文件。
import org.apache.commons.pool.BasePoolableObjectFactory;
public class BasePoolableObjectFactorySample
extends BasePoolableObjectFactory {
private int counter = 0;
public Object makeObject() throws Exception {
return String.valueOf(counter++);
}
}
5. ObjectPool的分類
l StackObjectPool 利用java.util.Stack對象來保存對象池里的對象。
l SoftReferenceObjectPool 利用java.util.ArrayList對象來保存對象池里的對象。
l GenericObjectPool利用一個org.apache.commons.collections.CursorableLinkedList對象來保存對象池里的對象。