简体   繁体   English

Future.cancel(false)为执行中的任务返回true

[英]Future.cancel(false) returning true for task in execution

Future.cancel(false) should, in my opinion, only return true if it was actually possible to prevent the task's execution. 在我看来,Future.cancel(false)只有在实际上可以阻止任务执行时才返回true。

But from code below we can see that it is contradicting. 但是从下面的代码我们可以看出它是矛盾的。

As the task is canceld it should not print "Not expecting this statement!!!" 由于任务是癌症,它不应该打印"Not expecting this statement!!!"

public class Test {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        final boolean[] canceled = { false };
        ScheduledFuture<?> future = executor.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    if (canceled[0])
                        System.out.println("Not expecting this statement!!!");
                } catch (InterruptedException e) {
                }
            }
        }, 0, TimeUnit.SECONDS);
        Thread.sleep(100);
        canceled[0] = future.cancel(false);

        executor.shutdown();
        executor.awaitTermination(2, TimeUnit.SECONDS);
    }
}

Unfortunately output of this program is "Not expecting this statement!!!" 不幸的是,这个程序的输出是“不期待这个声明!!!”

Can some one explain this behavior. 有人可以解释这种行为。

Because you call canceled[0] = future.cancel(false); 因为你调用canceled[0] = future.cancel(false); with parameter false . 参数为false From javadoc of Future.cancel : 来自Future.cancel javadoc:

If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task. 如果任务已经启动,则mayInterruptIfRunning参数确定执行此任务的线程是否应该在尝试停止任务时被中断。

@param mayInterruptIfRunning {@code true} if the thread executing this task should be interrupted; @param mayInterruptIfRunning {@code true}如果执行此任务的线程应该被中断; otherwise, in-progress tasks are allowed to complete 否则,允许完成正在进行的任务

When you call cancel , your task has already started and you allow it to complete, so cancel operation is actually successful and return true , if you call canceled[0] = future.cancel(true); 当你调用cancel ,你的任务已经开始并允许它完成,所以取消操作实际上是成功的,如果你调用canceled[0] = future.cancel(true); ,则返回true canceled[0] = future.cancel(true); , you'll not see the output. ,你不会看到输出。

In your code, boolean[] canceled is shared between two threads and there is no synchronized access to this variable. 在您的代码中, boolean[] canceled在两个线程之间共享,并且没有对此变量的同步访问。 So, the results will be unexpected. 所以,结果会出乎意料。 Also from the documentation of https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean) , it will return false if the task could not be cancelled, typically because it has already completed normally. 另外,从https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)的文档中,如果无法取消任务,它将返回false,通常是因为它已经正常完成。 Try adding a log after cancelling the task to see which one gets executed first (though it might not help always) 尝试在取消任务后添加日志,以查看哪一个首先被执行(尽管它可能总是没有帮助)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM