[
https://issues.apache.org/jira/browse/POOL-407?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Phil Steitz updated POOL-407:
-----------------------------
Fix Version/s: 3.0
> Threads get stuck when idleObjects list is empty.
> -------------------------------------------------
>
> Key: POOL-407
> URL: https://issues.apache.org/jira/browse/POOL-407
> Project: Commons Pool
> Issue Type: Bug
> Affects Versions: 2.8.1
> Reporter: Sarthak Shukla
> Priority: Major
> Fix For: 3.0
>
>
> While borrowing object from pool, threads are getting stuck. I initialised
> the pool size as 1. And had 3 threads created. First thread enters
> borrowObject method, since there are no idle objects to poll from, it will
> create one object and move forward.
> {code:java}
> p = (PooledObject)this.idleObjects.pollFirst();
> if (p == null) {
> p = this.create();
> if (p != null) {
> create = true;
> }
> } {code}
> The other two threads will also follow same path and check for idle
> objects(there are none), will try to create one object but the pool size is
> set to 1. Thus, the two threads will move forward and enter
> *idleObjects.takeFirst()* function. Value of blockWhenExhausted is true and
> borrowMaxWaitMillis is -1 as we don't want timeout.
> {code:java}
> if (blockWhenExhausted) {
> if (p == null) {
> if (borrowMaxWaitMillis < 0L) {
> p = (PooledObject)this.idleObjects.takeFirst();
> } else {
> p = (PooledObject)this.idleObjects.pollFirst(borrowMaxWaitMillis,
> TimeUnit.MILLISECONDS);
> }
> }
> if (p == null) {
> throw new NoSuchElementException("Timeout waiting for idle object");
> }
> }{code}
> Now, the main thread does *this.factory.activateObject(p);* and object gets
> activated. Now, when the validation is checked *validate =
> this.factory.validateObject(p);* it comes out to be false as provider might
> have been disconnected.
> So, the object is destroyed by calling *this.destroy(p);*
> {code:java}
> private void destroy(PooledObject<T> toDestroy) throws Exception {
> toDestroy.invalidate();
> this.idleObjects.remove(toDestroy);
> this.allObjects.remove(new
> BaseGenericObjectPool.IdentityWrapper(toDestroy.getObject()));
> try {
> this.factory.destroyObject(toDestroy);
> } finally {
> this.destroyedCount.incrementAndGet();
> this.createCount.decrementAndGet();
> }
> }{code}
> The object which was created is now destroyed and removed from idleObject and
> allObjects list. Now, the other two threads are still waiting to take object
> from idle objects list but there are no object present. Hence, the two
> threads are in wait state for infinite period and the application waits
> forever until we kill the process.
> {code:java}
> public E takeFirst() throws InterruptedException {
> this.lock.lock();
> Object var2;
> try {
> Object x;
> while((x = this.unlinkFirst()) == null) {
> this.notEmpty.await();
> }
> var2 = x;
> } finally {
> this.lock.unlock();
> }
> return var2;
> } {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)