FutureTask 的自定义取消

cra*_*fty 5 java concurrency

我已经实现了自定义取消逻辑,如实践中的并发中所述。

使用 newTaskFor 在任务中封装非标准取消

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

是否有一个简单的解决方案来取消所有正在进行的任务。我曾尝试覆盖 ThreadPoolExecutor 上的关闭方法,但我无权访问工作人员列表。我希望能够通过关闭执行程序来取消所有内容,因为它在多个地方用于提交任务,是否有简单的解决方案?

sjl*_*lee 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
        }
    }
Run Code Online (Sandbox Code Playgroud)

您也可以调用 cancelAllActiveTasks() 或重写 shutdownNow() 来调用它。我不喜欢的一件事是必须从队列中删除任务,因为它不是恒定时间操作。