Sarthak Shukla created POOL-407:
-----------------------------------
Summary: 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
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.
{quote}p = (PooledObject)this.idleObjects.pollFirst();
if (p == null) {
p = this.create();
if (p != null) {
create = true;
}
}
{quote}
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.
{quote}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");
}
}
{quote}
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);*
{quote}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();
}
}
{quote}
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.
{quote}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;
}
{quote}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)