Details
-
Bug
-
Status: Closed
-
Blocker
-
Resolution: Fixed
-
2.4.2, 2.5.0, 2.6.0, 2.7.0, 2.8.0, 2.9.0
-
None
Description
The method `brrowObject` is not thread safe with `destroy` or `clear` method.
The reason is when use GenericKeyedObjectPool#destroy method,it did not ensure the Atomicity of destroy object from the ObjectDeque。
This may cause in the GenericKeyedObjectPool#borrowObject method,may get the wrong number of GenericKeyedObjectPool.ObjectDeque#getCreateCount when need to create. And the GenericKeyedObjectPool#borrowObject will block until timeout.
Here is the sample test code to recur the bug:
// code placeholder public class CommonPoolMultiThreadTest { public static void main(String[] args) { GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig(); config.setMaxTotalPerKey(1); config.setMinIdlePerKey(0); config.setMaxIdlePerKey(-1); config.setMaxTotal(-1); config.setMaxWaitMillis(TimeUnit.SECONDS.toMillis(5)); GenericKeyedObjectPool<Integer, Integer> testPool = new GenericKeyedObjectPool<>( new KeyedPooledObjectFactory<Integer, Integer>() { @Override public PooledObject<Integer> makeObject(Integer key) throws Exception { System.out.println("start to create"); return new DefaultPooledObject<>(10); } @Override public void destroyObject(Integer key, PooledObject<Integer> p) throws Exception { System.out.println("start to destroy"); Thread.sleep(2000); } @Override public boolean validateObject(Integer key, PooledObject<Integer> p) { return true; } @Override public void activateObject(Integer key, PooledObject<Integer> p) throws Exception { // do nothing } @Override public void passivateObject(Integer key, PooledObject<Integer> p) throws Exception { // do nothing } }, config ); int borrowKey = 10; Thread t = new Thread(() -> { try { while (true) { Integer integer = testPool.borrowObject(borrowKey); testPool.returnObject(borrowKey, integer); Thread.sleep(10); } } catch (Exception e) { e.printStackTrace(); System.exit(1); } }); Thread t2 = new Thread(() -> { try { while (true) { testPool.clear(borrowKey); Thread.sleep(10); } } catch (Exception e) { e.printStackTrace(); System.exit(1); } }); t.start(); t2.start(); } }
Attachments
Issue Links
- links to