[ 
https://issues.apache.org/jira/browse/POOL-419?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17925267#comment-17925267
 ] 

Raju Gupta commented on POOL-419:
---------------------------------

[~ggregory] . Sorry for bothering you. Let me know if you would like to review 
this or else I can close the PR. Thanks!

> GenericObjectPoolConfig getNumActive return negative value
> ----------------------------------------------------------
>
>                 Key: POOL-419
>                 URL: https://issues.apache.org/jira/browse/POOL-419
>             Project: Commons Pool
>          Issue Type: Bug
>    Affects Versions: 2.12.0
>            Reporter: john ms
>            Priority: Major
>
> We've notice unexpected counting that is return from getNumActive .
> and it means that allObjects and idleObjects are out of sync.
> Calling returnObject and invalidateObject on the same pooled object from two 
> different threads is causing  getNumActive to return negative value. 
> Why two threads are working on the same object at the same time and the real 
> running use case is much complex to described and not relevant, I think.  
> Bellow is a simple program to demo the behavior 
> {*}Expected result{*}: 
> getNumActive=0
>  
> {*}Actual result{*}: 
> getNumActive=\{negative number}
> If it help debugging the RC, I've notice that returnObject is not 
> synchronized over pooled object and verify it's status before using it, like 
> it's done in invalidateObject. 
> {*}Workaround{*}:
> Synchronize the  pooled object before calling returnObject/invalidateObject 
>  
> Java 17
> {code:java}
> public class PoolObject extends BasePooledObjectFactory<PoolObject> {
>     @Override
>     public PoolObject create() {
>         return new PoolObject();
>     }
>     @Override
>     public PooledObject<PoolObject> wrap(PoolObject poolObject) {
>         return new DefaultPooledObject<>(poolObject);
>     }
>     @Override
>     public void passivateObject(PooledObject<PoolObject> pooledObject) {
>     }
> }{code}
>  
> {code:java}
> public static void main (String [] args) throws Exception {
>     ExecutorService executor = Executors.newCachedThreadPool();
>     GenericObjectPoolConfig<PoolObject> poolConfig = new 
> GenericObjectPoolConfig<>();
>     poolConfig.setMaxTotal(200000);
>     poolConfig.setMaxIdle(200000);
>     poolConfig.setMinIdle(200000);
>     ObjectPool<PoolObject> objectPool = new GenericObjectPool<>(new 
> PoolObject(), poolConfig);
>     for (int i=0; i<1000000; i++){
>        PoolObject poolObject= objectPool.borrowObject();
>        FutureTask invalidateObject = new FutureTask<>(() -> {
>           Thread.sleep(RandomUtils.nextInt(0,10));
>           //synchronized (poolObject) { // Workaround bug
>              objectPool.invalidateObject(poolObject);
>           //}
>           return true;
>        });
>        executor.execute(invalidateObject);
>        FutureTask returnObject = new FutureTask<>(() -> {
>           Thread.sleep(RandomUtils.nextInt(0,10));
>           //synchronized (poolObject) { // Workaround bug
>              objectPool.returnObject(poolObject);
>           //}
>           return true;
>        });
>        executor.execute(returnObject);
>     }
>     Thread.sleep(2000);
>     executor.shutdown();
>     System.out.println("getNumActive=" + objectPool.getNumActive());
> }{code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to