アプリケーションにがありGenericKeyedObjectPool
ます。メソッドで閉じることはできclose
ますが、借用したすべてのオブジェクトがクライアントからプールに戻る(そしてプールが破棄される)のをどのように待つ必要がありますか?
のようなものが必要ですExecutorService.awaitTermination
。
アプリケーションにがありGenericKeyedObjectPool
ます。メソッドで閉じることはできclose
ますが、借用したすべてのオブジェクトがクライアントからプールに戻る(そしてプールが破棄される)のをどのように待つ必要がありますか?
のようなものが必要ですExecutorService.awaitTermination
。
GenericKeyedObjectPool
必要なawaitTermination
メソッドを持つのラッパーを作成します。close
プールが閉じられ、すべてのオブジェクトが返された場合は、および呼び出しをチェックしreturnObject
てラッチをデクリメントできます(=このプールから現在借用されているインスタンスの総数はゼロです)。
public final class ListenablePool<K, V> {
private final GenericKeyedObjectPool<K, V> delegate;
private final CountDownLatch closeLatch = new CountDownLatch(1);
private final AtomicBoolean closed = new AtomicBoolean();
public ListenablePool(final KeyedPoolableObjectFactory<K, V> factory) {
this.delegate = new GenericKeyedObjectPool<K, V>(factory);
}
public V borrowObject(final K key) throws Exception {
return delegate.borrowObject(key);
}
public void returnObject(final K key, final V obj) throws Exception {
try {
delegate.returnObject(key, obj);
} finally {
countDownIfRequired();
}
}
private void countDownIfRequired() {
if (closed.get() && delegate.getNumActive() == 0) {
closeLatch.countDown();
}
}
public void close() throws Exception {
try {
delegate.close();
} finally {
closed.set(true);
countDownIfRequired();
}
}
public void awaitTermination() throws InterruptedException {
closeLatch.await();
}
public void awaitTermination(final long timeout, final TimeUnit unit)
throws InterruptedException {
closeLatch.await(timeout, unit);
}
public int getNumActive() {
return delegate.getNumActive();
}
// other delegate methods
}
すべてのオブジェクトが返されるのを待たずに、閉じるだけで安全です。
GenericKeyedObjectPool.html#close()のドキュメントから:
プールを閉じます。プールが閉じられると、borrowObject()はIllegalStateExceptionで失敗しますが、returnObject(Object)とinvalidateObject(Object)は引き続き機能し、返されたオブジェクトは戻り時に破棄されます。