Deadlock in GenericObjectPool. Between borrowObject() and evict()
-----------------------------------------------------------------
Key: POOL-184
URL: https://issues.apache.org/jira/browse/POOL-184
Project: Commons Pool
Issue Type: Bug
Affects Versions: 1.5.5
Environment: java 1.6.0_24
Ubuntu 10.10
Reporter: Adrian Nistor
Hi,
I am encountering a deadlock in GenericObjectPool. It appears in version 1.5.5
and also in revision 1079385 (March 8th 2011).
The deadlock manifests when calling borrowObject() and evict() in parallel. I
have inlined a test that exposes this problem. For this test, the expected
output is:
Expected output:
0
1
2
3
4
.....
498
499
DONE
But when the bug manifests (almost always for this test), the output is:
Bug output:
0
1
2
3
4
When the bug manifests, the test does not finish, it just gets stuck after
printing several values (in this run: 0 1 2 3 4, but in other runs may be
0 1 2 .. 18 or 0 1 2 or some other value).
When the loop limit is small (e.g., 11 instead of 5000), the test does finish.
Also, when running sequentially:
Pool.borrowObject();
Pool.evict();
or vice-versa
Pool.evict();
Pool.borrowObject();
the test still finishes.
Is this a bug? Is there a patch for it?
Thanks!
Adrian
================================================================================
This test is for version 1.5.5. For revision 1079385 one should replace
setMaxActive() with setMaxTotal()
================================================================================
package org.apache.commons.pool.impl;
import org.apache.commons.pool.PoolableObjectFactory;
public class Test01
{
public static void main(String[] args) throws Exception
{
Test01 test = new Test01();
test.test();
}
SimpleFactory Factory = null;
GenericObjectPool Pool = null;
Object Obj = null;
public void test() throws Exception
{
Factory = new SimpleFactory();
Pool = new GenericObjectPool(Factory);
Pool.setMaxActive(1);
Pool.addObject();
for(int i=0; i<5000; i++)
{
Thread one = new MyThread(1);
Thread two = new MyThread(2);
one.start();
two.start();
one.join();
two.join();
Pool.returnObject(Obj);
if(i%10==0)
{
System.out.println(i/10);
}
}
System.out.println("DONE");
}
private class MyThread extends Thread
{
int _tid;
public MyThread(int tid)
{
_tid = tid;
}
public void run()
{
try
{
if(_tid == 1)
{
Obj = Pool.borrowObject();
}
if (_tid == 2)
{
try
{
Pool.evict();
} catch (Exception e) {}
}
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
}
private class SimpleFactory implements PoolableObjectFactory
{
public SimpleFactory() {}
public Object makeObject() { return new String("testing"); }
public void destroyObject(Object obj) {}
public boolean validateObject(Object obj) {return true;}
public void activateObject(Object obj) throws Exception {}
public void passivateObject(Object obj) throws Exception {}
public boolean isThrowExceptionOnActivate() {return true;}
}
}
================================================================================
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira