为什么不能从 Runnable 命令本身关闭 ScheduledExecutorService?

Why ScheduledExecutorService cannot be shutted down from the Runnable command itself?

我想安排一个每 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 控制台中看到以下内容:

右上角的红色按钮显示 JVM 仍然是 运行,因为 ExecutorService 是 运行。我将日志放在 while 中,我看到循环永远不会终止。

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

我正在使用 JDK6。

在 运行 方法中检查线程池的终止状态:

while(!scheduler.isTerminated()) {}

这将执行以下操作:

  • 执行运行nable 的线程将进入循环。
  • 由于线程仍然是 "active",即尚未完成 run,则条件为真("not terminated = true")。
  • 这将使线程保持在循环中 永远

所以删除 "while" 线程池将按预期终止。

P.S.: 如果你想在主执行线上等待池被终止,你可以使用 awaitTermination.