geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Manu George" <manu.t.geo...@gmail.com>
Subject Re: Thread Pool Deadlock
Date Sun, 02 Sep 2007 18:23:49 GMT
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?

Secondly the api docs say that we shouldn't do executor.getQueue().put(r);
Will this not create problems with unexpected behaviour?

Thanks
Manu


On 9/2/07, David Jencks <david_jencks@yahoo.com> 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
>
>

Mime
View raw message