|
Ok, there is no way to force the bad case to happen in a unit test.
I created a test case, and with it you can just hope the bug happens. And i tested it several times, it always happens. But maybe you need to run it several time to get your luck. Here is the instruction: From the thread dump you should able to find one pooled thread wait on GenericObjectPool for ever like this:
Locked ownable synchronizers:
From the heap dump you should able to see the GenericObjectPool is empty. There is another way to see this bug easily, but you need a multithread enabled debuger, for example, Netbeans(See http://www.netbeans.org/kb/docs/java/debug-multithreaded.html And this bug should be called resource leak, not deadlock. My bad.
Finally all threads try to borrow objects from the empty pool will block indefinitely. Thanks, Shuyang!
The test case demonstrates the problem nicely. A simple fix for the specific case identified here is to recheck latch.mayCreate() inside the synch(latch) block, i.e. change GenericObjectPool line 1101 revision 792217 to if (latch.getPair() == null && !latch.mayCreate()) That "fix" does not fully address the problem though, as it deals only with the control path called out in the bug report. We should look at all other latch state tests and scope of synchronization on latches. Just curious, do you guys have a plan to upgrade Commons Pool's jdk requirement to 1.5+ ?
By the concurrent package, you can avoid the fragile synchronized, wait and notify, and also use the spin lock instead of the old monitor lock to get a performance gain. Great! Hope it comes out soon
Hi, I believe this problem is hitting me in pre-production, where all the threads are dealocked at
java.lang.Thread.State: WAITING (on object monitor)
Can I have an update on this issue? Is there a patch I can apply to workaround this problem? Hi Filippo,
No sure is your problem the same as the one i found. Because your thread dump looks different. Do you know which version of commons pool you have? GenericObjectPool.java:942 is javadoc in 1.5.2 If you sure about they are the same, you can try Phil's solution. Even though there maybe more bugs like this, but this fix should help your problem. Fillippo: From the line numbers in the stack trace above, it looks like a) the pool version is 1.4 and b) you have configured the pool to block indefinitely (maxWait < 0) when the pool is exhausted and c) the pool is exhausted. The issue reported in this ticket applies only to pool 1.5+.
Assuming I have interpreted the line numbers in the trace right, most likely what is going on is your application is not closing connections and you are exhausting the pool. This is related to
In short, when testing to see if allocate() had assigned an object, checking latch.getPair()==null was insufficient. It is also necessary to check latch.mayCreate()==false This has been patched in trunk and will be fixed in 1.5.3 The attached test case now runs without locking up. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
POOL-147. It would be great to have a test case to demonstrate the reported issue. In any case, the execution sequence should not result in a deadlock; rather a resource leak and one thread blocking indefinitely.