Future.cancel() 如果不中断,该怎么办?

2022-09-01 21:03:31

来自 Future.cancel() 上的 java docs

boolean cancel(boolean mayInterruptIfRunning)

尝试取消此任务的执行。如果任务已完成、已取消或由于某些其他原因无法取消,则此尝试将失败。如果成功,并且在调用 cancel 时此任务尚未启动,则此任务应永远不会运行。如果任务已启动,则 mayInterruptIfRunning 参数确定是否应中断执行此任务的线程以尝试停止该任务。

我的问题是,如果 mayInterruptIfRunning 是假的,取消会做什么?
如果任务已经运行,它如何取消或停止执行?


答案 1

如果它没有中断,它只会告诉被取消的未来。您可以通过isCancelled()进行检查,但是如果您不手动检查,则不会发生任何事情。

下面的示例代码显示了如何执行此操作。

private static FutureTask<String> task = new FutureTask<String>(new Callable<String>() {

    @Override
    public String call() throws Exception {
        while (!task.isCancelled()) {
            System.out.println("Running...");
            Thread.sleep(1000);
        }
        return "The End";
    }

});

public static void main(String[] args) throws InterruptedException {
    new Thread(task).start();
    Thread.sleep(1500);
    task.cancel(false);
}

任务启动,并在 1.5 次迭代后被告知停止。它将继续睡眠(如果你打断它,它不会)然后完成。


答案 2

如果任务已经开始,则不会执行任何操作,并且可能中断如果运行为 false,

下面是取消()

public boolean cancel(boolean mayInterruptIfRunning) {
    if (state != NEW)
        return false;
    if (mayInterruptIfRunning) {
        if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
            return false;
        Thread t = runner;
        if (t != null)
            t.interrupt();
        UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
    }
    else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
        return false;
    finishCompletion();
    return true;
}

我们可以看到,如果 mayInterruptIfRunning 是 false,cancel() 只需将状态从 NEW 更改为 CANCELLED 并返回 false,其他任何事情都不会执行