You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Executors.newSingleThreadExecutor()未保证执行输出顺序?

为什么Executors.newSingleThreadExecutor()未让"End."排在输出最后?

环境信息

  • JDK/Java 19
  • Windows 11 x64
  • IntelliJ IDEA 2022 Ultimate

测试代码

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();
            }
        }
    }

}

实际输出

Begin
End.
Printing zoo inventory
Printing record 0
Printing record 1
Printing record 2
Printing zoo inventory

参考资料引用

With a single-thread executor, results are guaranteed to be executed sequentially.
——《OCP Oracle Certified Professional Java SE 11 Developer - Complete Study Guide》第850页

问题解析

你误解了书中描述的范围:

  1. 书中的"sequentially"仅针对线程池内部的任务:SingleThreadExecutor保证的是提交给它的任务会在同一个工作线程中按提交顺序依次执行,从输出可以看到,三个提交的任务确实是按runnable1→runnable2→runnable1的顺序执行的,完全符合书中的描述。
  2. 主线程与线程池工作线程是独立异步的:主线程在提交任务给线程池后,不会等待任务执行完毕,会立刻继续执行后续代码(也就是打印"End.")。这两个线程的执行是并行的,主线程的打印操作自然会先于线程池任务的输出完成。

如果想要让"End."排在所有任务输出之后,可以在调用shutdown()后,调用awaitTermination()方法等待线程池任务全部完成:

try {
    executorService = Executors.newSingleThreadExecutor();
    System.out.println("Begin");
    executorService.execute(runnable1);
    executorService.execute(runnable2);
    executorService.execute(runnable1);
    executorService.shutdown();
    // 等待最多10秒,直到所有任务完成
    executorService.awaitTermination(10, java.util.concurrent.TimeUnit.SECONDS);
    System.out.println("End.");
} catch (InterruptedException e) {
    e.printStackTrace();
} finally {
    if (executorService != null && !executorService.isShutdown()) {
        executorService.shutdownNow();
    }
}

内容的提问来源于stack exchange,提问作者Đỗ Như Vỹ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:01:07