How to shutdown a GenericKeyedObjectPool safely?
Asked Answered
S

2

1

I have a GenericKeyedObjectPool in my application. I can close it with the close method but how should I wait for the clients to return (and the pool destroys) every borrowed object to the pool?

I need something like ExecutorService.awaitTermination.

Size answered 13/11, 2012 at 4:50 Comment(0)
S
2

Create a wrapper for the GenericKeyedObjectPool which has the required awaitTermination method. You can check the close and the returnObject calls and decrement a latch if the pool is closed and every object was returned (= the total number of instances current borrowed from this pool is zero).

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
}
Size answered 13/11, 2012 at 4:50 Comment(0)
G
1

You should be safe just closing it, without waiting for all objects to be returned.

From the docs of GenericKeyedObjectPool.html#close():

Closes the pool. Once the pool is closed, borrowObject() will fail with IllegalStateException, but returnObject(Object) and invalidateObject(Object) will continue to work, with returned objects destroyed on return.

Gook answered 13/11, 2012 at 5:8 Comment(1)
Thanks for the answer! The pooled objects are database/network connections, so it's more friendly for the remote systems to close them if it's possible. Anyway, it made me think that I might not want to wait forever for the object which might never be returned.Size

© 2022 - 2024 — McMap. All rights reserved.