You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Gautam Bakshi <ga...@gmail.com> on 2012/05/04 16:07:45 UTC

[pool] Does borrowObject block?

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.
*/

Re: [pool] Does borrowObject block?

Posted by Mark Thomas <ma...@apache.org>.
On 04/05/2012 23:25, Gautam Bakshi wrote:
> Thanks for the answer Miroslav.  This brings up a few other questions to
> me, mainly can I extend the life of a object in pool(these objects
> shouldn't be dying if there is work)?  Also, can I somehow specify a
> minimum limit of objects so I can have them match the number of threads I
> have(this way if the pool does get low the thread doesn't have to wait for
> it to be created)?

Hmm. A couple of points.

You are always going to see some blocking with a pooling implementation.
What you see with 1.5/1.6 is less then you'll see with 1.4 an earlier.
2.x (currently a work in progress) will have even less blocking.

If you each thread only uses one object at a time and you have a minimum
pool size equal to the number of threads why bother with a pool? Just
create an object when you create the thread and dedicate the object to
the thread.

Mark


> 
> On Fri, May 4, 2012 at 5:41 PM, Miroslav Pokorny <miroslav.pokorny@gmail.com
>> wrote:
> 
>> On Sat, May 5, 2012 at 12:07 AM, Gautam Bakshi <gautam.bakshi@gmail.com
>>> wrote:
>>
>>> 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?
>>>
>>> Hi Gautum,
>>
>> What your describing is normal behaviour, after all if you ask the pool for
>> an object and one is not available what else should it do. The best thing
>> is to wait(block) until another thread returns a pooled item and then
>> return with that. The reason for using pooling is typically the pooled
>> objects are expensive or limited resources which is why your code does not
>> simply create another one when it needs it, but rather waits its turn and
>> then returns the pooled object when its used.
>>
>> hth
>>
>> mP
>>
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [pool] Does borrowObject block?

Posted by Miroslav Pokorny <mi...@gmail.com>.
On Sat, May 5, 2012 at 8:25 AM, Gautam Bakshi <ga...@gmail.com>wrote:

> Thanks for the answer Miroslav.  This brings up a few other questions to
> me, mainly can I extend the life of a object in pool(these objects
> shouldn't be dying if there is work)?  Also, can I somehow specify a
> minimum limit of objects so I can have them match the number of threads I
> have(this way if the pool does get low the thread doesn't have to wait for
> it to be created)?
>
>
Hi Gautam

Most of your questions address the main properties that control a pool, and
of course all make perfect sense. The answer to the how is of course what
remains and i would suggest that you take a look at the javadoc or even the
provided tests, as they show how to exercise each and every feature.

hth

Re: [pool] Does borrowObject block?

Posted by Gautam Bakshi <ga...@gmail.com>.
Thanks for the answer Miroslav.  This brings up a few other questions to
me, mainly can I extend the life of a object in pool(these objects
shouldn't be dying if there is work)?  Also, can I somehow specify a
minimum limit of objects so I can have them match the number of threads I
have(this way if the pool does get low the thread doesn't have to wait for
it to be created)?

On Fri, May 4, 2012 at 5:41 PM, Miroslav Pokorny <miroslav.pokorny@gmail.com
> wrote:

> On Sat, May 5, 2012 at 12:07 AM, Gautam Bakshi <gautam.bakshi@gmail.com
> >wrote:
>
> > 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?
> >
> > Hi Gautum,
>
> What your describing is normal behaviour, after all if you ask the pool for
> an object and one is not available what else should it do. The best thing
> is to wait(block) until another thread returns a pooled item and then
> return with that. The reason for using pooling is typically the pooled
> objects are expensive or limited resources which is why your code does not
> simply create another one when it needs it, but rather waits its turn and
> then returns the pooled object when its used.
>
> hth
>
> mP
>

Re: [pool] Does borrowObject block?

Posted by Miroslav Pokorny <mi...@gmail.com>.
On Sat, May 5, 2012 at 12:07 AM, Gautam Bakshi <ga...@gmail.com>wrote:

> 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?
>
> Hi Gautum,

What your describing is normal behaviour, after all if you ask the pool for
an object and one is not available what else should it do. The best thing
is to wait(block) until another thread returns a pooled item and then
return with that. The reason for using pooling is typically the pooled
objects are expensive or limited resources which is why your code does not
simply create another one when it needs it, but rather waits its turn and
then returns the pooled object when its used.

hth

mP