如何使ScheduledExecutorService在其计划任务被取消时自动终止 [英] How to make a ScheduledExecutorService terminate automatically when its scheduled task is cancelled

查看:4937
本文介绍了如何使ScheduledExecutorService在其计划任务被取消时自动终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果网络连接已打开超过几个小时,我使用 ScheduledExecutorService 关闭网络连接。然而,在大多数情况下,网络连接在超时之前关闭,所以我取消 ScheduledFuture 。在这种情况下,我还希望执行器服务终止并释放它的线程池。

I'm using a ScheduledExecutorService to close a network connection if it has been open for more than several hours. In most cases however, the network connection is closed before the timeout is reached, so I cancel the ScheduledFuture. In this case, I also want the executor service to terminate and to release its thread pool.

令我惊讶的是,这不是开箱即用:虽然我有在执行器服务调度任务后调用 shutdown(),当其唯一的计划任务被取消时,执行器服务不会自动终止。从 ExecutorService.shutdown()的JavaDoc中,此行为甚至可能是正确的,因为可以说已取消的任务未被执行:

To my surprise, this does not work out of the box: Although I have called shutdown() on the executor service after scheduling the task, the executor service does not terminate automatically when its only scheduled task is cancelled. From the JavaDoc of ExecutorService.shutdown() this behaviour may even be correct because arguably the cancelled task has not been "executed":


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

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

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.

我的问题是如果可以更改:是否可以配置执行器服务

My question is if this can be changed: Is it possible to configure an executor service to automatically terminate when its only scheduled task is cancelled?

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

Or the same question written as a JUnit test:

@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!?
}


推荐答案

c> ScheduledThreadPoolExecutor ( Executors.newScheduledThreadPool )返回的实际类型文档:

From the ScheduledThreadPoolExecutor (the actual type returned by Executors.newScheduledThreadPool) documentation:


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

When a submitted task is cancelled before it is run, execution is suppressed. By default, such a cancelled task is not automatically removed from the work queue until its delay elapses. While this enables further inspection and monitoring, it may also cause unbounded retention of cancelled tasks. To avoid this, set setRemoveOnCancelPolicy(boolean) to true, which causes tasks to be immediately removed from the work queue at time of cancellation.

这是一个 ScheduledThreadPoolExecutor 方法。我不相信有可能纯粹使用 ScheduledExecutorService 界面来解决这个问题。

This is a ScheduledThreadPoolExecutor method though. I don't believe it's possible to solve this purely using the ScheduledExecutorService interface.

这篇关于如何使ScheduledExecutorService在其计划任务被取消时自动终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆