geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <>
Subject Re: Thread Pool Deadlock
Date Sun, 02 Sep 2007 21:36:35 GMT

On Sep 2, 2007, at 11:23 AM, Manu George wrote:

> Hi David,
>            Thanks for the explanation.
> In case of waitWhenBlocked=true what will be the expected behaviour if
> I set the poolsize as 1? Currently on debugging I see that the calling
> thread gets parked and then never gets resumed if already 1 thread is
> executing. Any idea why would this be happening?

I suspect that the first thread is submitting work which needs a  
second thread, or for the first one to complete.  In other words it  
won't work with waitWhenBlocked = true.
> Secondly the api docs say that we shouldn't do executor.getQueue 
> ().put(r);
> Will this not create problems with unexpected behaviour?

I didn't see this documentation, can you point me to it?  I don't see  
how this could create unexpected problems, but I might have missed  

david jencks
> Thanks
> Manu
> On 9/2/07, David Jencks <> wrote:
>> I don't think the current implementation is actually wrong under
>> normal use (where you just configure the gbean in xml and don't
>> change its settings at runtime).
>> I think it would be better to set up the executor in its constructor
>> (keeping the waitWhenBlocked as a constructor parameter).  There's a
>> constructor for ThreadPoolExecutor we can use that lets us set
>> everything at once.
>> I think the wait when blocked configuration is correct as it stands.
>> I suggest that using the LinkedBlockingQueue is appropriate when
>> waitWhenBlocked is false but not when its true.
>> IMO the caller-runs policy is not appropriate for use in j2ca since
>> the work manager can notify you if the work is rejected.  Thus tying
>> up your own thread is not appropriate since it eliminates the
>> possibility of the caller taking corrective action.
>> thanks
>> david jencks
>> On Sep 2, 2007, at 8:46 AM, Manu George wrote:
>>> Hi,
>>>         I was investigating why setting the resourceAdapter poolsize
>>> to 1 and using it in an Mdb for sequential message processing was
>>> failing and found that the org.apache.geronimo.pool.ThreadPool class
>>> in geronimo contains a ThreadPoolExecutor instance created with the
>>> constructor
>>> new ThreadPoolExecutor(
>>>             poolSize, // core size
>>>             poolSize, // max size
>>>             keepAliveTime, TimeUnit.MILLISECONDS,
>>>             new SynchronousQueue());
>>> The default behaviour is to reject the Runnables supplied when  
>>> the no
>>> of active threads equals the pool size.
>>> Now the ThreadPool class has a setWaitWhenBlocked method which when
>>> called makes it wait. Setting  this makes the pool enter into a
>>> deadlock. The reason for this is the WaitWhenBlockedPolicy used to
>>> process rejection. In this class there is a
>>> executor.getQueue().put(r);
>>> Now the API docs mention that once you handoff the queue to a
>>> ThreadPoolExecutor we should not directly modify the queue as it may
>>> result in unpredictable behaviour. So this is a bug.
>>> As a solution for this what I did was
>>>  ThreadPoolExecutor p = new ThreadPoolExecutor(
>>>             poolSize, // core size
>>>             poolSize, // max size
>>>             keepAliveTime, TimeUnit.MILLISECONDS,
>>>             new LinkedBlockingQueue<Runnable>(queueSize));
>>> Now this results in upto queue size of Runnables that can be  
>>> submitted
>>> of which poolsize will be the no of parallel executions. More than
>>> queue size will be rejected.
>>> We can also set the rejection handler to the CallerRunsPolicy  
>>> when the
>>> quesize is exceeded and the waitWhenBlocked flag is true.
>>> This results in me getting the scenario working. I am not yet  
>>> sure why
>>> the SynchronousQueue was used in this case, so thats why I  
>>> changed the
>>> queuing strategy. So Is this an acceptable approach for fixing this
>>> issue?
>>> Secondly do we want a behaviour of rejection of work items when  
>>> queue
>>> is full? Setting the CallerRunsPolicy actually results in graceful
>>> degradation when load exceeds capacity by increasing backlog at the
>>> TCP/IP layer. Would be happy if some of the experts would comment on
>>> this
>>> Thanks
>>> Manu

View raw message