Removing all queued tasks of an ThreadPoolExecutor

三世轮回 提交于 2019-11-28 07:19:51

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.

ZZ Coder

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.

As ExecutorService.shutdown() is not doing enough and ExecutorService.shutdownNow() is doing too much I guess you have to write up something in the middle: remember all your submitted tasks and remove them manually after (or before) calling shutdown().

This is an old question, but in case this helps somebody else: you could set a volatile boolean when you call shutdown(), and have each submitted task terminate if that boolean is set before really starting. This will allow tasks which have genuinely started to complete, but will prevent queued tasks from starting their actual activity.

Bombe's answer is exactly what you want. shutdownNow() stops everything using the nuke and pave approach. This is the best thing you can do, short of subclassing the implementation of ThreadPoolExecutor that you're using.

iman

You can try allowCoreThreadTimeOut(true);

You could create your own task queue and pass it to ThreadPoolExecutor constructor:

int poolSize = 1; // number of threads
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>();
Executor executor = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, queue);

When you clear the queue somewhere in your code then the remaining tasks will not be executed:

queue.clear();

A crazy and unclean solution which might work (not real thought through or tested) would be to overwrite the interrupt() of your WorkerTasks which only in case some global value is set refuse to shutdown when interrupt() is called on them by shutdownNow().

That should allow you to use shutdownNow() no?

Tell your thread pool to shutdown, getQueue, for-each the result into individual Runnables, remove each Runnable using the remove method. Depending on the type of queue, you might be able to halt the removes early based on return values.

Basically, this is grabbing the queue and clearing it, only clearing via the methods that work. Instead of manually remembering all the submissions, you use the fact the thread pool already has to remember all the submissions. However, you will probably need to make a defensive copy of the queue, as I think it's a live view, and therefore removing would probably cause a concurrent modification exception if you were iterating/for-eaching over the live view.

Doesn't awaitTermination(long timeout, TimeUnit unit) work after shutdown?

executor.shutdown(); executor.awaitTermination(60, TimeUnit.SECONDS)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!