[ https://issues.apache.org/jira/browse/POOL-391?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Phil Steitz closed POOL-391. ---------------------------- > GenericKeyedObjectPool is not thread safe when invoke method `borrowObject` > and `destroy` simultaneously > --------------------------------------------------------------------------------------------------------- > > Key: POOL-391 > URL: https://issues.apache.org/jira/browse/POOL-391 > Project: Commons Pool > Issue Type: Bug > Affects Versions: 2.4.2, 2.5.0, 2.6.0, 2.7.0, 2.8.0, 2.9.0 > Reporter: Codievilky August > Priority: Blocker > Fix For: 2.12.0 > > Original Estimate: 24h > Remaining Estimate: 24h > > 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:java} > // 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(); > } > } > {code} > -- This message was sent by Atlassian Jira (v8.20.10#820010)