【发布时间】:2020-05-20 00:24:35
【问题描述】:
我编写了一个小代码,用于练习 Executors 和 Threads。它由以下内容组成:
- 使用无限队列创建大小为 3 的固定线程池。
- 将 3 个无限循环的任务 (
while(true)) 提交到池中(然后 所有线程都被占用) - 提交第 4 个任务,该任务将在队列中等待。
- executor.shutdown() 并执行 println 以查看我的活动任务和任务计数如何。
- 将标志设置为 false 以停止无限
while然后执行 println 看看我是如何进行活动任务和任务计数的 - 用
mayInterruptIfRunning=true取消所有期货,然后 做一个 println 看看我是如何制作活动任务和任务计数的 有
这是代码:
public class Main {
private static ThreadPoolExecutor fixexThreadPool;
public static void main(String[] args) throws InterruptedException {
System.out.println("Creating fixed thread pool of size 3 and infinite queue.");
fixexThreadPool = new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
final Boolean[] flag = new Boolean[1];
flag[0] = true;
List<Future> futures = new ArrayList<>();
System.out.println("Submiting 3 threads");
for (int i = 0; i < 3; i++) {
futures.add(fixexThreadPool.submit(() -> {
int a = 1;
while (flag[0]) {
a++;
}
System.out.println("Finishing thread execution.");
}));
}
System.out.println("Done submiting 3 threads.");
System.out.println(String.format("Active count: %s | Completed task count: %s | task count: %s", fixexThreadPool.getActiveCount(), fixexThreadPool.getCompletedTaskCount(), fixexThreadPool.getTaskCount()));
Thread.sleep(3000L);
System.out.println("Submitting a 4th thread.");
futures.add(fixexThreadPool.submit(() -> {
int a = 1;
while (flag[0]) {
a++;
}
System.out.println("Finishing thread execution");
}));
System.out.println(String.format("Active count: %s | Completed task count: %s | task count: %s", fixexThreadPool.getActiveCount(), fixexThreadPool.getCompletedTaskCount(), fixexThreadPool.getTaskCount()));
System.out.println("Executor shutdown");
fixexThreadPool.shutdown();
System.out.println(String.format("Active count: %s | Completed task count: %s | task count: %s", fixexThreadPool.getActiveCount(), fixexThreadPool.getCompletedTaskCount(), fixexThreadPool.getTaskCount()));
Thread.sleep(2000L);
System.out.println("Setting flag to false.");
flag[0] = false;
Thread.sleep(2000L);
System.out.println(String.format("Active count: %s | Completed task count: %s | task count: %s", fixexThreadPool.getActiveCount(), fixexThreadPool.getCompletedTaskCount(), fixexThreadPool.getTaskCount()));
System.out.println("Cancelling all futures.");
futures.forEach(f -> f.cancel(true));
System.out.println(String.format("Active count: %s | Completed task count: %s | task count: %s", fixexThreadPool.getActiveCount(), fixexThreadPool.getCompletedTaskCount(), fixexThreadPool.getTaskCount()));
}
}
这是执行的输出:
- 创建大小为 3 的固定线程池和无限队列。
- 提交 3 个主题
- 已完成提交 3 个线程。
- 活动计数:3 |已完成任务计数:0 |任务数:3
- 提交第 4 个线程。
- 活动计数:3 |已完成任务计数:0 |任务数:4
- 执行程序关闭
- 活动计数:3 |已完成任务计数:0 |任务数:4
- 将标志设置为 false。
- 活动计数:3 |已完成任务计数:0 |任务数:4
- 取消所有期货。
- 活动计数:3 |已完成任务计数:0 |任务数:4
有几件事我不明白。
- 为什么关闭executor后,还有活跃的线程?
- 为什么在将标志更改为 false 以中断无限循环后,无限
while不会中断? - 为什么在取消每一个future之后,还有活跃的线程?
- 无论是否将标志更改为 false、关闭执行程序甚至取消所有期货,我的程序都不会停止运行。这是为什么呢?
提前致谢!!
【问题讨论】:
-
尝试阅读
shutdown和shutdownNow的 javadocs 并了解它们的区别。此外,由于线程正在疯狂循环,它们将消耗最大 cpu。其他指令可能没有机会执行。 -
嗨@ScaryWombat,我已经改为shutdownNow(),程序继续运行。唯一改变的是第4个排队的任务被删除了。
标签: java java.util.concurrent java-threads