Java 如果不中断,Future.cancel() 会做什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21445224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:45:48  来源:igfitidea点击:

What does Future.cancel() do if not interrupting?

javamultithreadinginterruptfuture

提问by Tom

From java docs on Future.cancel()

来自Future.cancel() 上的 java 文档

boolean cancel(boolean mayInterruptIfRunning)

Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interruptedin an attempt to stop the task.

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

My question is what does cancel do if mayInterruptIfRunning is false?
how does it cancel or stop the task from executing if it has already been run?

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

采纳答案by zapl

If it is not interrupting it will simply tell the future that is is cancelled. You can check that via isCancelled()but nothing happens if you don't check that manually.

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

Below example code shows how you could do it.

下面的示例代码显示了如何做到这一点。

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);
}

The task is started, and after 1.5 iterations told to stop. It will continue sleeping (which it would not if you interrupted it) and then finish.

任务开始,在 1.5 次迭代后被告知停止。它会继续休眠(如果你打断它就不会)然后完成。

回答by Paul Bellora

My question is what does cancel do if mayInterruptIfRunning is false? how does it cancel or stop the task from executing if it has already been run?

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

If the task has already started running, and mayInterruptIfRunningis false, then there is nothing to be done. In Java, interrupting a thread is considered to be the only safe way of stopping it short of completion - and even that requires the task to "comply" by checking for interruption at some implementation-specific interval.

如果任务已经开始运行,并且mayInterruptIfRunningfalse,那么就没有什么可做的了。在 Java 中,中断线程被认为是在未完成时停止线程的唯一安全方法 - 甚至这也需要任务通过在某些特定于实现的时间间隔检查中断来“遵守”。

Related: How do you kill a thread in Java?

相关:你如何在 Java 中杀死一个线程?

回答by Slogen

nothing will be done if the task has already started and mayInterruptIfRunning is false,

如果任务已经开始并且 mayInterruptIfRunning 为 false,则不会执行任何操作,

below is the cancel()

下面是取消()

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;
}

we can see that if mayInterruptIfRunning is false,cancel() just change state from NEW to CANCELLED and return false,nothing else will be done

我们可以看到,如果 mayInterruptIfRunning 为 false,cancel() 只是将状态从 NEW 更改为 CANCELLED 并返回 false,则不会执行其他操作