How to make a ScheduledExecutorService terminate automatically when its scheduled task is cancelled

大城市里の小女人 提交于 2019-12-07 08:34:28

问题


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.

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?


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

回答1:


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

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.

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



来源:https://stackoverflow.com/questions/23369952/how-to-make-a-scheduledexecutorservice-terminate-automatically-when-its-schedule

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!