commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gautam Bakshi <gautam.bak...@gmail.com>
Subject [pool] Does borrowObject block?
Date Fri, 04 May 2012 14:07:45 GMT
Hi Everyone,

I'm trying to pool some objects and share them but I noticed blocking in
the threads. I'm a bit new to Java so not sure if this is a problem with my
lack of experience or something specific to pools. Here's some code that
replicates the problem(Create 10 threads and share 20 objects, do this in a
long loop so you can catch the blocking). If you profile it(Java visualvm
or yourkit in the thread view), you'll notice that borrowObject seems to be
blocking the thread. So the question is, is this normal behavior or am I
doing something wrong? Is there any way I can get around it?

Here's some code to replicate the problem(run it and use a profiler to see
the blocking of threads):

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;

public class main{

    public static void main(String[] a){

        ObjectPool<Foo> fpool = new GenericObjectPool<Foo>(new
FooPoolableObjectFactory(), 20);

        ExecutorService tpool = Executors.newFixedThreadPool(10);

        for(int i = 0; i < 900000000; ++i){

            tpool.submit(new FooWorker(fpool));

        }

    }
}

class Foo{

    private static int pk = 0;

    private int count = 0;

    public final int id;

    public Foo(){

        id = pk++;

    }

    public int increment(){

        return ++count;

    }
}

class FooWorker implements Runnable{

    private ObjectPool<Foo> fpool;

    public FooWorker(ObjectPool<Foo> fpool){

        this.fpool = fpool;

    }

    @Override

    public void run(){

        Foo foo = null;

        try{

            foo = fpool.borrowObject();

            //System.out.println(foo.id + ": " + foo.increment());

        }

        catch(Exception e){

            e.printStackTrace();

        }

        finally{

            // This is done in a finally block to ensure the object is
returned to the pool

            if(foo != null){

                try{

                    fpool.returnObject(foo);

                }

                catch(Exception e){

                    e.printStackTrace();

                }

            }

        }

    }
}

class FooPoolableObjectFactory extends BasePoolableObjectFactory<Foo>{

    @Override

    public Foo makeObject() throws Exception{

        return new Foo();

    }
}

/*
Example output:
1: 1
0: 1
2: 1
3: 1
2: 2
0: 2
2: 3
0: 3

1: 2
3: 2

The number on the left is the id of the foo object being used.
The number on the right is the value of the foo object.

Notice how the foos are being reused.
*/

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message