我在Windows 11 x64中使用JDK/Java 19,IntelliJ IDEA 2022终极版。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ZooInfo {
public static void main(String[] args) {
ExecutorService executorService = null;
Runnable runnable1 = () -> System.out.println("Printing zoo inventory");
Runnable runnable2 = () -> {
for (int i = 0; i < 3; i++) {
System.out.println("Printing record " + i);
}
};
try {
executorService = Executors.newSingleThreadExecutor();
System.out.println("Begin");
executorService.execute(runnable1);
executorService.execute(runnable2);
executorService.execute(runnable1);
System.out.println("End.");
} finally {
if (executorService != null) {
executorService.shutdown();
}
}
}
}
// Result:
// Begin
// End.
// Printing zoo inventory
// Printing record 0
// Printing record 1
// Printing record 2
// Printing zoo inventory
我读了第850页,书OCP Oracle认证专业Java SE 11开发人员-完整学习指南),他们说
使用单线程执行器,可以保证按顺序执行结果。
为什么Executors.newSingleThreadExecutor()
不保证订单?(“end”不在控制台结果的行尾。)
3条答案
按热度按时间5jvtdoz21#
您的程序有 * 两个 * 线程:
1.主函数,从中调用
executorService.execute
和所有其他函数。Executors.newSingleThreadExecutor()
的线程你传递给
newSingleThreadExecutor
的runnables确实会在那个线程上顺序运行,但这并不意味着你的程序中的 * 所有东西 * 都会相对于那些runnables顺序运行。(例如,通过调用executorService.shutdown()
,然后调用awaitTermination(...)
以等待现有作业完成)。您还可以对每个runnable使用submit
而不是execute
;这将给予一个Future
,然后您可以调用get(...)
以等待它完成(您必须为每个runnable执行此操作。executorService.invokeAll(...)
使此操作更容易一些。jchrr9hc2#
您忽略了等待执行者服务完成其工作。
您忽略了
ExecutorService
的Javadoc中显示的shutdownAndAwaitTermination
中提供的所有样板代码。您的原始线程碰巧比执行服务的线程更早地完成了它的工作,这就是独立线程的本质:各种线程在各种时间量内完成各种工作量。
2ekbmq323#
因为main方法独立于
executorService = Executors.newSingleThreadExecutor();