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

时间:2017-04-04 04:59:04

标签: java future

在我看来,Future.cancel(false)只有在实际上可以阻止任务执行时才返回true。

但是从下面的代码我们可以看出它是矛盾的。

由于任务已取消,因此不应打印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); } }

{{1}}

不幸的是,这个程序的输出是“不期待这个声明!!!”

有人可以解释这种行为。

2 个答案:

答案 0 :(得分:5)

因为您使用参数canceled[0] = future.cancel(false);来呼叫false。来自Future.cancel的javadoc:

  

如果任务已经启动,那么mayInterruptIfRunning参数确定执行此任务的线程是否应该在尝试停止任务时被中断。

     

@param mayInterruptIfRunning {@code true}如果执行此任务的线程应该被中断;否则,允许正在进行的任务完成

当您致电cancel时,您的任务已经启动,并且您已完成此任务,因此取消操作实际上已成功并返回true,如果您致电canceled[0] = future.cancel(true);,则为&#39 ; ll看不到输出。

答案 1 :(得分:0)

在您的代码中,boolean[] canceled在两个线程之间共享,并且没有对此变量的同步访问。所以,结果会出乎意料。同样来自https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)的文档,如果任务无法取消,它将返回false,通常是因为它已经正常完成。 尝试在取消任务后添加一个日志,看看哪一个先被执行(尽管它可能总是没有帮助)