[ 
https://issues.apache.org/jira/browse/POOL-407?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17612860#comment-17612860
 ] 

Marten Gajda commented on POOL-407:
-----------------------------------

[~ggregory] the missing classes are in the src/main folder of the project 
[https://github.com/dmfs/POOL-407]

I probably can file a PR by the end of the week.

> 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
>
> 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)

Reply via email to