如何从其他任务中取消ScheduledFuture任务并优雅地结束?

时间:2015-09-23 13:27:27

标签: java multithreading java-8 scheduled-tasks scheduledexecutorservice

我正在玩ScheduledExecutorService。我想要做的是启动一个简单的自动收报机(每秒一个滴答)并安排另一个任务(5秒后)取消第一个任务。然后阻止主线程直到所有内容完成,这应该在两个任务完成后(+ - 5秒)。

这是我的代码:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable tickTask = () -> System.out.println("Tick");
ScheduledFuture<?> scheduledTickTask = executor.scheduleAtFixedRate(tickTask, 0, 1, TimeUnit.SECONDS);
Runnable cancelTask = () -> scheduledTickTask.cancel(true);
executor.schedule(cancelTask, 5, TimeUnit.SECONDS);
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

让我感到惊讶的问题是,BLOCKS好像还有一些正在运行的任务。为什么? cancelTask应立即结束,scheduledTickTask刚刚取消,那么问题是什么?

1 个答案:

答案 0 :(得分:5)

根据ExecutorService.awaitTermination的Javadoc(强调我的):

  

阻止所有任务完成执行关闭请求,或发生超时,或当前线程中断,以先发生者为准。

这意味着您需要先调用shutdown,如下所示:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable tickTask = () -> System.out.println("Tick");
ScheduledFuture<?> scheduledTickTask = executor.scheduleAtFixedRate(tickTask, 0, 1, TimeUnit.SECONDS);
Runnable cancelTask = () -> {
    scheduledTickTask.cancel(true);
    executor.shutdown();
};
executor.schedule(cancelTask, 5, TimeUnit.SECONDS);
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

在你的情况下,超时永远不会发生,因为你几乎把它设置为&#34;无穷大&#34;并且当前线程不会中断。