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 f
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?
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.
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.
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();
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()
.
You can try allowCoreThreadTimeOut(true);