我正在尝试使用类scheduleAtFixedRate
的方法ScheduledExecutorService
的示例。代码是:
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
IntStream.range(0, 4).forEach(i -> service.scheduleAtFixedRate(() -> {try {
System.out.println(i + " task completed!");
} catch (Exception e) {
e.printStackTrace();
}},
0, 3, TimeUnit.SECONDS));
service.shutdown();
输出结果为:
1 task completed!
2 task completed!
0 task completed!
为什么不执行所有4个任务?
如果省略service.shutdown();
,则所有任务也会被执行并重复执行,但会导致内存泄漏。根据文档,任何在关闭之前都应该执行注册任务。
此外,如果我使用Thread
暂停当前Thread.sleep()
一段时间,则输出包含以下所有任务:
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
IntStream.range(0, 4).forEach(i -> service.scheduleAtFixedRate(() -> {try {
System.out.println(i + " task completed!");
} catch (Exception e) {
e.printStackTrace();
}},
0, 3, TimeUnit.SECONDS));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.shutdown();
输出:
0 task completed!
3 task completed!
2 task completed!
1 task completed!
这是方法scheduleAtFixedRate
的预期行为吗?
更新
当我毫不拖延地使用submit
代替scheduleAtFixedRate
时,行为接近预期。调用shutdown()
可以完成所有4个任务,而shutdownNow()
仅限3:
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
IntStream.range(0, 4).forEach(i -> service.submit(() -> {
System.out.println(i + " task completed");}));
service.shutdown();
如果我不使用ScheduledExcecutorService
并使用ExecutorService
代替:
ExecutorService service = Executors.newFixedThreadPool(4);
IntStream.range(0, 4).forEach(i -> service.submit(() -> {
System.out.println(i + " task completed");}));
service.shutdown();
然后,无论我使用shutdown()
shutdownNow()
的{{1}},所有4个任务都会完成。
ScheduledExecutorService
似乎在任务提交方面略有不同,可能在shutdown()
和shutdownNow()
上。
答案 0 :(得分:-1)
在ExecutorService.class
的文档中找到了这个
此方法不会等待以前提交的任务 完成执行。使用{@link #awaitTermination awaitTermination} 这样做。
查看此Link了解详情。
从我的PC我发现有时所有四个线程都完成执行。这取决于调用shudown
的时间。如果要等待线程完成,请使用awaitTermination
方法。
当您让main
线程进入睡眠状态时,执行shutdown
需要花费一些时间,直到那时所有任务都结束了。