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

如何用Java ExecutorService实现线程内有序、整体并行的操作执行

问题分析与解决方案

你的代码无法达到预期效果的核心原因是:printA和printB仅仅是向线程池提交任务,线程池会并行调度这些任务,即便你在外部线程中先调用printA再调用printB,线程池中的A任务和B任务依然会交叉执行,无法保证同一逻辑单元内的A全部完成后再执行B。

下面提供两种可行的解决方案:

方案一:用CountDownLatch控制A任务全部完成后再执行B

这种方式保留了将A、B拆分为独立线程任务的逻辑,同时通过内部CountDownLatch确保所有A执行完毕后才提交B任务:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch outerLatch = new CountDownLatch(5);

        for (int i = 1; i <= 5; i++) {
            executorService.execute(() -> {
                try {
                    // 提交所有A任务并等待完成
                    CountDownLatch aCompleteLatch = new CountDownLatch(5);
                    for (int j = 0; j < 5; j++) {
                        executorService.execute(() -> {
                            System.out.println("A");
                            aCompleteLatch.countDown();
                        });
                    }
                    aCompleteLatch.await(); // 阻塞直到所有A执行完毕

                    // 提交所有B任务
                    for (int j = 0; j < 5; j++) {
                        executorService.execute(() -> {
                            System.out.println("B");
                        });
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    outerLatch.countDown();
                }
            });
        }

        outerLatch.await();
        executorService.shutdown();
        if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
        }
    }
}

方案二:在当前线程顺序执行A、B打印

如果不需要将A、B拆分为独立线程任务,直接在每个外层线程中先打印所有A,再打印所有B,逻辑更简洁:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch countDownLatch = new CountDownLatch(5);

        for (int i = 1; i <= 5; i++) {
            executorService.execute(() -> {
                try {
                    // 连续打印5个A
                    for (int j = 0; j < 5; j++) {
                        System.out.println("A");
                    }
                    // 连续打印5个B
                    for (int j = 0; j < 5; j++) {
                        System.out.println("B");
                    }
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        countDownLatch.await();
        executorService.shutdown();
        if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
        }
    }
}

两种方案都能保证每个逻辑单元内的printB相关操作在printA全部完成后执行,同时外层的5个任务依然保持并行执行的特性。

内容的提问来源于stack exchange,提问作者Pushpak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:07:47