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 Thread Pool Deadlock
Date Sun, 02 Sep 2007 15:46:12 GMT
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