在java程序中對於資源,例如數據庫連接,這類不能並行共享的資源對象,一般採用資源池的方式進行管理。
資源池一般要實現 1)獲取資源對象 getObject(): 從資源池中取出對象
2) returnObject() : 資源用完以後,將資源放回對象池
3) 資源對象(代理)調用close()方法時, 資源返回對象池。 對於有close方法的資源,一般是採用此方式。
以下是一個非常簡單的資源對象池的實現
public class SimplePool<T> {
// 回收資源的方法名
private String closemethod = "close";private LinkedBlockingQueue<T> sources = new LinkedBlockingQueue<T>();
private List<T> origins = new ArrayList<T>();
public SimplePool(){
}
public T getSource() throws InterruptedException {
return this.sources.take();
}
/**
* 將資源加入到池中, 併爲資源對象生成代理對象,放到隊列中。
* @param t
*/
public synchronized void addSource(T t) {
origins.add(t);
Handler handler = new Handler(t);
T pt = (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler);
sources.offer(pt);
}
/**
* Java 動態代理實現的InvocationHandler, 代理對象調用close方法時,
* 將資源帶來對象放回到隊列中,從而實現資源自動回收
*/
class Handler implements InvocationHandler {
Handler(T t) {
target = t;
}
T target;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equalsIgnoreCase(SimplePool.this.closemethod)) {
SimplePool.this.sources.put((T) proxy);
return null;
}
return method.invoke(target, args);
}
}
/**
* 獲取可用資源數量
* @return
*/
public int count() {
return sources.size();
}
/**
* 獲取已放入池中的資源數量
* @return
*/
public int size(){
return this.origins.size();
}
}
這個資源池的代碼非常簡單, 當然,還可以在代碼中增加 ObjectFactory<T> 的工廠對象,在getSource方法中,但資源不足時,就可以調用這ObjectFactory<T>生成新的資源對象。另外,像connection對象可能還需要進行可用性檢測等。