[
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)