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

voh*_*oho 4 java multithreading scheduled-tasks java-8 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);
Run Code Online (Sandbox Code Playgroud)

让我感到惊讶的问题是,BLOCKS好像还有一些正在运行的任务.为什么?该cancelTask应立即结束,并且scheduledTickTask只是取消了,所以这是什么问题?

Tun*_*aki 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);
Run Code Online (Sandbox Code Playgroud)

在您的情况下,超时将永远不会发生,因为您实际上将其设置为"无穷大"并且当前线程不会中断.