java 为什么Executors.newSingleThreadExecutor()不能保证该顺序?

htrmnn0y  于 2022-11-27  发布在  Java
关注(0)|答案(3)|浏览(124)

我在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”不在控制台结果的行尾。)

5jvtdoz2

5jvtdoz21#

您的程序有 * 两个 * 线程:
1.主函数,从中调用executorService.execute和所有其他函数。

  1. Executors.newSingleThreadExecutor()的线程
    你传递给newSingleThreadExecutor的runnables确实会在那个线程上顺序运行,但这并不意味着你的程序中的 * 所有东西 * 都会相对于那些runnables顺序运行。(例如,通过调用executorService.shutdown(),然后调用awaitTermination(...)以等待现有作业完成)。您还可以对每个runnable使用submit而不是execute;这将给予一个Future,然后您可以调用get(...)以等待它完成(您必须为每个runnable执行此操作。executorService.invokeAll(...)使此操作更容易一些。
jchrr9hc

jchrr9hc2#

您忽略了等待执行者服务完成其工作。
您忽略了ExecutorService的Javadoc中显示的shutdownAndAwaitTermination中提供的所有样板代码。

executorService = Executors.newSingleThreadExecutor();
System.out.println("Begin");
executorService.execute(runnable1);
executorService.execute(runnable2);
executorService.execute(runnable1);
shutdownAndAwaitTermination( executorService ) ;  // Block here to wait for executor service to complete its assigned tasks. 
System.out.println("End.");

您的原始线程碰巧比执行服务的线程更早地完成了它的工作,这就是独立线程的本质:各种线程在各种时间量内完成各种工作量。

2ekbmq32

2ekbmq323#

因为main方法独立于executorService = Executors.newSingleThreadExecutor();

相关问题