为什么无法从Runnable命令本身关闭ScheduledExecutorService?

时间:2016-05-13 07:32:48

标签: java concurrency executorservice scheduledexecutorservice

我想安排一个将每1秒执行一次的命令。该命令将递增计数器,当计数器达到某个限制时,执行将停止,ExecutorService将关闭。所以我写了以下代码片段:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class SchedulerTest {

    private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    private ScheduledFuture<?> scheduledTask;

    private AtomicInteger counter = new AtomicInteger(0);

    public SchedulerTest() {

    }

    private void check() {
        Runnable task = new Runnable() {

            @Override
            public void run() {
                int currentValue = counter.incrementAndGet();                   
                System.out.println(currentValue);

                if(currentValue == 5) {
                    scheduledTask.cancel(false);

                    scheduler.shutdown();
                    while(!scheduler.isTerminated()) {}
                }
            }
        };

        scheduledTask = scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);                                
    }

    public static void main(String[] args) {
        new SchedulerTest().check();
    }
}

以上代码仅用于演示目的。

现在我可以在Eclipse控制台中看到以下内容:

console image

右上角的红色按钮表示当ExecutorService正在运行时JVM仍在运行。我已将日志放在while内,我看到循环永远不会终止。

我想知道这种行为背后的原因是什么?有没有办法从Runnable命令本身终止ExecutorService?

我正在使用JDK6。

1 个答案:

答案 0 :(得分:2)

在run方法中,检查线程池的终止状态:

while(!scheduler.isTerminated()) {}

这将执行以下操作:

  • 执行该runnable的线程将进入循环。
  • 由于线程仍处于“活动状态”,即尚未完成run,条件将为真(“未终止=真”)。
  • 这将使线程永远

因此删除“while”并且线程池将按预期终止。

P.S。:如果您想等待池的主执行行终止,您可以使用awaitTermination