[ https://issues.apache.org/jira/browse/POOL-407?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17612791#comment-17612791 ]
Gary D. Gregory commented on POOL-407: -------------------------------------- [~dmfs] Please provide your test as a GitHub PR as it currently does not look like it would even compile since there is no Foo or FooPool types in your example folder. We need a failing test to debug ;) > 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)