代码之家  ›  专栏  ›  技术社区  ›  crafty

未来任务的自定义取消

  •  4
  • crafty  · 技术社区  · 15 年前

    我在实践中实现了并发中描述的自定义取消逻辑。

    Encapsulating nonstandard cancellation in a task with newTaskFor .

    这样做很好,我可以在将来调用cancel,任务按预期被取消。我需要能够通过调用“shutdownNow”方法来破坏我正在使用的executor服务,但是这个方法只是调用线程上的interupt,这意味着我的自定义取消逻辑永远不会被调用。由于我的任务使用非阻塞套接字,中断线程不起作用,因此我有自定义的取消逻辑。

    是否有一个简单的解决方案来取消所有正在进行的任务。我试图重写ThreadPoolExecutor上的shutdown方法,但我没有访问工作进程列表的权限。我想通过关闭执行器来取消所有操作,因为它在多个地方用于提交任务,有没有一个简单的解决方案?

    1 回复  |  直到 15 年前
        1
  •  1
  •   sjlee    15 年前

    正如约翰所指出的,最好能让你的任务中断。然后,您可以简单地依赖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
            }
        }