Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing all queued tasks of an ThreadPoolExecutor

i have this rather simple question about the ThreadPoolExecutor. I have the following situation: I have to consume objects from a queue, create the appropiate worker tasks for them and submit them to the ThreadPoolExecutor. This is quite simple. But within a shutdown scenario many workers may be queued to execution. Since one of those tasks might be running for an hour, and i want a relativly fast graceful shutdown of the application i want to discard all queued tasks from the ThreadPoolExecutor while the already processing tasks should be completed normally.

The ThreadPoolExecutor documentation has a remove() method but only allows specific tasks to be removed. purge() only works for already canceled Future tasks. My idea was to clear the queue holding all queued tasks. The ThreadPoolExecutor provides access to this internal queue but the documentation states:

Method getQueue() allows access to the work queue for purposes of monitoring and debugging. Use of this method for any other purpose is strongly discouraged.

So grabbing this queue and clearing it is not an option. Also, this snippet of the documentation says:

Two supplied methods, remove(java.lang.Runnable) and purge() are available to assist in storage reclamation when large numbers of queued tasks become cancelled.

How? Sure, i can maintain a list of all tasks i submitted to the executor and in a shutdown case i iterate over all entries and remove them from the ThreadPoolExecutor with the remove() method... but... come on, this is a waste of memory and a hassle to maintain this list. (Removing already executed tasks for example)

I appreciate any hints or solutions!

like image 378
Malax Avatar asked Nov 05 '09 10:11

Malax


People also ask

How do I stop all threads in ExecutorService?

Using shutdownNow() The shutdownNow() is a hard signal to destroy ExecutorService immediately along with stopping the execution of all in-progress and queued tasks. Use this method, when we want the application to stop processing all tasks immediately.

How do I cancel an ExecutorService task?

Learn to cancel a task submitted to an executor service if the task still has to be executed and/or has not been completed yet. We can use the cancel() method of Future object that allows making the cancellation requests.

How do you terminate a Threadpool?

shutdownNow() should be used to shutdown the thread pool to gracefully exiting the application.

Do you need to shutdown down ExecutorService?

ExecutorService must be shutdown explicitly to reclaim the resources (CPU & Memory) occupied by threads which have already finished their job but still exist.


2 Answers

I used to work on an app with long running threads. We do this at shutdown,

BlockingQueue<Runnable> queue = threadPool.getQueue(); List<Runnable> list = new ArrayList<Runnable>(); int tasks = queue.drainTo(list); 

The list is saved to a file. On startup, the list is added back to the pool so we don't lose any jobs.

like image 110
ZZ Coder Avatar answered Sep 23 '22 04:09

ZZ Coder


Have you considered wrapping the ExecutorService? Create a

CleanShutdownExecutorService implements Executor  

that delegates all calls to another Executor, but keeps the Futures in a list of its own. CleanShutdownExecutorService can then have a cancelRemainingTasks() method that calls shutdown(), then calls cancel(false) on all the Futures in its list.

like image 26
Sbodd Avatar answered Sep 26 '22 04:09

Sbodd