As John noted, it would be better if you could interrupt your tasks. Then you can simply rely on ThreadPoolExecutor to interrupt all worker threads to arrange for their cancellation.
If this is not possible, you can add additional logic to the ThreadPoolExecutor to achieve what you want. This is somewhat related and may not be very pretty for some (and may hurt performance a bit), but I think it will do its job. I think that basically you need to keep a list of active tasks yourself. The key is to override the beforeExecute () and afterExecute () methods:
public class MyExecutor extends ThreadPoolExecutor { private final Queue<RunnableFuture> activeTasks = new LinkedBlockingQueue<RunnableFuture>(); ... protected void beforeExecute(Thread t, Runnable r) { RunnableFuture task = (RunnableFuture)r; activeTasks.add(task); } protected void afterExecute(Thread t, Runnable r) { RunnableFuture task = (RunnableFuture)r; activeTasks.remove(task); } public void cancelAllActiveTasks() { for (RunnableFuture f: activeTasks) { f.cancel(true);
You can call cancelAllActiveTasks () or override shutDownNow () to call it. The only thing I donβt like about this is to remove the task from the queue, as this is not a constant time operation.
sjlee source share