One of the things I encounter from time to time is the missing handling of the RejectedExecutionException (thrown by the Executor). This exception can be thrown when the executor:
- is shutting down. When it is shutting down, you don’t want it to execute accept new task: the shutdown should have a higher priority than the acceptance of new tasks.
- the executor doesn’t want to accept the task. If you are using a bounded BlockingQueue as workqeue in the ThreadPoolExecutor (bounded = good, makes your system degrade gracefully) and the queue is full, the Executor doesn’t block until the task can be placed (this is something not all developers realize), but rejects the tasks by throwing the RejectedExecutionException.
So the RejectedExecutionException is a ‘normal’ situation that could happen in a healthy system. So make sure you are dealing with the RejectedExecutionException. If you don’t deal with this situation, unwanted behavior, like disappearance of tasks, could be the consequence.
May 27, 2009 at 8:08 pm |
Hi – nice post….just what I was looking for…what do u think is the best way to handle this exception…
In my app we TRY to execute tasks in async IF POSSIBLE. So I am thingking of handling this exception as below…let me know if there is a better way
List tasksToPillSequentially=new ArrayList();
try
{
executorService.submit(task);
}
catch(RejectedExecutionException re)
{
tasksToPillSequentially.add(task);
}
for(Task task: tasksToPillSequentially)
{
task.execute()
}
Thanks in advance!
May 27, 2009 at 8:30 pm |
Depending on the situation, it could be a very good solution. Essentially it is the same behaviour the CallerRunsPolicy provides.
But with asynchronous communication, you always have to ask yourself: does my system want to process too much work? If the executor starts complaining with a RejectedExecutionException, is my system overloaded?
Ps:
I think it is really crap that the ThreadPoolExecutor doesn’t block out of the box. That is why I created the BlockingExecutor quite some time ago:
http://prometheus.codehaus.org/javadoc/main/org/codehaus/prometheus/blockingexecutor/BlockingExecutor.html. If you want I can give you some pointers how to make the normal ThreadPoolExecutor blocking..
Prometheus at the moment is not active, I’m spending all my time on http://multiverse.googlecode.com.. Prometheus = old school and old school concurrent is way too complex.
May 28, 2009 at 2:02 pm |
thx for the response…i will stick with my current design…the reason for not using CallerRunsPolicy is that it will DISCARD the tasks if the thread pool/executor is shutdown…thats a bummer…the tasks should always be executed in my case; async if possible, sequentially otherwise.
I’ve seen the MultiVerse project earlier…do u need any help on that…I’d like to contribute
May 28, 2009 at 2:06 pm |
Multiverse needs all the help it can get
So if you want to help, you are welcome!
May 29, 2009 at 7:49 pm |
great..starting with Recommended literature….