如何使ScheduledExecutorService在其计划任务被取消时自动终止

我正在使用ScheduledExecutorService来关闭网络连接,如果它已打开超过几个小时。 但是,在大多数情况下,网络连接在达到超时之前关闭,因此我取消了ScheduledFuture 。 在这种情况下,我还希望执行程序服务终止并释放其线程池。

令我惊讶的是,这不是开箱即用的:虽然我在调度任务后在执行程序服务上调用了shutdown() ,但执行程序服务在其唯一的计划任务被取消时不会自动终止。 从ExecutorService.shutdown()的JavaDoc中,这种行为甚至可能是正确的,因为可以说取消的任务还没有被“执行”:

void java.util.concurrent.ExecutorService.shutdown()

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。 如果已经关闭,调用没有其他影响。

我的问题是,是否可以更改:是否可以将执行程序服务配置为在其唯一的计划任务被取消时自动终止?


或者写为JUnit测试的同一个问题:

 @Test public void testExecutorServiceTerminatesWhenScheduledTaskIsCanceled() throws Exception { ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); Runnable task = new Runnable() { @Override public void run() { // ... } }; ScheduledFuture scheduledTask = scheduler.schedule(task, 2000, TimeUnit.MILLISECONDS); scheduler.shutdown(); // do more configuration here... Thread.sleep(1000); scheduledTask.cancel(false); Thread.sleep(100); assertThat(scheduler.isTerminated(), is(true)); // ... so that this passes!? } 

ScheduledThreadPoolExecutorExecutors.newScheduledThreadPool返回的实际类型)文档:

在提交的任务在运行之前取消时,将禁止执行。 默认情况下,此类已取消的任务不会自动从工作队列中删除,直到其延迟过去。 虽然这可以进一步检查和监控,但也可能导致取消任务的无限制保留。 要避免这种情况,请将setRemoveOnCancelPolicy(boolean)设置为true,这会导致在取消时立即从工作队列中删除任务。

这是一个ScheduledThreadPoolExecutor方法。 我不相信使用ScheduledExecutorService接口纯粹解决这个问题。