为什么不能从 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.
我想安排一个每 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.