我已经实现了自定义取消逻辑,如实践中的并发。
Encapsulating nonstandard cancellation in a task with newTaskFor。
这很好,我可以在未来调用取消,任务按预期取消。我需要能够通过调用“shutdownNow”方法来破坏我正在使用的执行器服务,但是这个方法只是在线程上调用interupt,这意味着我的自定义取消逻辑永远不会被调用。由于我的任务使用非阻塞套接字中断线程不起作用,因此我有自定义取消逻辑。
是否有一个简单的解决方案可以取消正在进行的所有任务。我试过在ThreadPoolExecutor上覆盖shutdown方法但是我没有访问worker列表的权限。我希望能够通过关闭执行程序取消所有内容,因为它在几个地方用于提交任务,是否有一个简单的解决方案?
答案 0 :(得分:1)
正如约翰所指出的那样,最好是让你的任务可以中断。然后你可以简单地依赖ThreadPoolExecutor来中断所有工作线程以便有序取消。
如果无法做到这一点,您可以在ThreadPoolExecutor中添加其他逻辑以实现您想要的效果。它有点牵扯,可能对某些人来说不太好(并且可能会损害性能),但我认为它将完成工作。我认为基本上你需要自己维护一个活动任务列表。关键是覆盖beforeExecute()和afterExecute()方法:
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); // invokes your custom cancellation logic
}
}
您可以调用cancelAllActiveTasks()或覆盖shutDownNow()来调用它。我不喜欢这件事的一件事是必须从队列中删除任务,因为它不是一个恒定时间的操作。