Lee,

The additional synchronization was needed for correct thread-safety.
Unfortunately it does make the pool a bit of a bottleneck as your
example demonstrates.

If you feel you don't need all of that synchronization and the pool
will be correct enough without it then I suggest you take the source
to a pool implementation you like, copy it to a private package and
modify it.

Someday I hope a much more concurrent pool is written but that is hard
thing to get right. Until then that is the best I have for you.

On 5/3/07, Lee Breisacher <[EMAIL PROTECTED]> wrote:
I'm running into a performance problem and I think it can be attributed to some 
overly aggressive locking in GenericObjectPool>addObject(). Or perhaps I'm not 
using the APIs just right, and someone can point out a better path for me.

Here's the scenario:

- I have a GenericObjectPool with a minIdle setting so it always tries to keep 
a minimum number of objects in the pool.

- My makeObject() method can sometimes take several seconds to make a poolable 
object (yes, perhaps *that* is the cause of my problems, but there's nothing I 
can do about it).

- Sequence of events:
1. Thread A borrows an object that causes the pool to be completely empty.

2. The ensureMinIdle() method (called from the Evictor thread) calls 
addObject() which locks the pool and calls my (long-running) makeObject().

3. Thread B wants to borrow an object, but notices the pool is empty so it 
waits (that's logic in my code).

4. Thread A finishes with its borrowed object and calls returnObject(), but 
returnObject cannot enter because the pool is locked from step 2 (which is 
still running in makeObject()). So thread A is stuck waiting on the pool's lock.

5. Finally, makeObject() finishes and adds the newly made object to the pool.

6. Thread A's returnObject now gets the lock and returns the object to the pool.

The performance problem is at step 4 -- there's an object available for Thread 
B to use, but it cannot get a hold of it.

Note that this was not a problem with commons-pool 1.2 - several more "synchronized" were added to 
methods in version 1.3. Perhaps those "synchronized" are necessary to prevent other kinds of 
deadlock or race conditions, but perhaps the locks are a bit too aggressive? In particular, it seems to me 
that the call "out" to the client's makeObject() method in addObject() should release the pool's 
lock. In fact, isn't it always a bit risky to hold onto a lock during a call out to a client method?

Has anyone else run into this problem? Am I way off base in my addObject() 
suggestion?

Thanks,

Lee

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--
Sandy McArthur

"He who dares not offend cannot be honest."
- Thomas Paine

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to