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

如何按顺序执行Java线程?现有代码问题及替代方案咨询

问题分析与解决方案

首先纠正你代码里的两个核心问题:

  1. flag变量未声明,必须添加volatile修饰的静态变量:private static volatile boolean flag = false;,否则连编译都通不过。
  2. 原逻辑完全搞反了:打印"Second Function"的线程里写的是while(flag),但初始flag是false,所以这个循环直接跳过,根本不会执行里面的打印和countDown操作,这才是导致countDownLatch.await()一直阻塞的真正原因,不是volatile的可见性问题。

如果你硬要让两个线程严格按First Function→Second Function的顺序执行,哪怕违背异步初衷,以下几种方法可行:


方法1:直接串行执行(最简单粗暴)

既然要顺序执行,干脆不搞异步启动,直接按顺序调用Runnable的run()方法,或者启动线程后调用join()等待前一个线程执行完:

修改executeAndWait方法:

public static void executeAndWait(List<Runnable> runnables) throws InterruptedException {
    for (Runnable r : runnables) {
        Thread t = new Thread(r);
        t.start();
        t.join(); // 等待当前线程执行完再启动下一个
    }
}

注意要把runnables的顺序调整过来(原列表第一个是打印Second的,第二个是First的):

List<Runnable> runnables = Arrays.asList(
    () -> {
        try {
            Thread.sleep(100);
            System.out.println("First Function");
            countDownLatch.countDown();
        } catch(Exception e) {}
    },
    () -> {
        try {
            Thread.sleep(100);
            System.out.println("Second Function");
            countDownLatch.countDown();
        } catch(Exception e) {}
    }
);

这样启动后,第一个线程执行完First Function,第二个线程才会启动执行Second Function,完全符合顺序要求。


方法2:用CountDownLatch严格控制线程执行顺序

保留异步启动,但通过CountDownLatch让打印Second的线程等待打印First的线程执行完:

重新设计代码逻辑:

public class Application {
    // 用一个CountDownLatch控制Second线程等待First线程
    private static CountDownLatch firstDoneLatch = new CountDownLatch(1);
    private static CountDownLatch allDoneLatch = new CountDownLatch(2);

    public static void executeAndWait(List<Runnable> runnables) {
        runnables.forEach(r -> new Thread(r).start());
    }

    public static void main(String[] args) throws InterruptedException  {
        List<Runnable> runnables = Arrays.asList(
            // 打印Second的线程:先等待First线程完成
            () -> {
                try {
                    firstDoneLatch.await(); // 等待First线程执行完
                    Thread.sleep(100);
                    System.out.println("Second Function");
                    allDoneLatch.countDown();
                } catch(Exception e) {}
            },
            // 打印First的线程:执行完后通知Second线程
            () -> {
                try {
                    Thread.sleep(100);
                    System.out.println("First Function");
                    firstDoneLatch.countDown(); // 通知Second线程可以执行了
                    allDoneLatch.countDown();
                } catch(Exception e) {}
            }
        );
        executeAndWait(runnables);
        allDoneLatch.await();
        System.out.println("Main Execution Completed!");
    }
}

这里两个线程同时启动,但打印Second的线程会先阻塞在firstDoneLatch.await(),直到打印First的线程执行完并调用countDown(),才会继续执行,完美实现顺序要求。


方法3:使用Semaphore(信号量)控制

原理和CountDownLatch类似,用信号量让Second线程等待First线程释放许可:

public class Application {
    private static Semaphore semaphore = new Semaphore(0);
    private static CountDownLatch allDoneLatch = new CountDownLatch(2);

    public static void executeAndWait(List<Runnable> runnables) {
        runnables.forEach(r -> new Thread(r).start());
    }

    public static void main(String[] args) throws InterruptedException  {
        List<Runnable> runnables = Arrays.asList(
            () -> {
                try {
                    semaphore.acquire(); // 等待许可
                    Thread.sleep(100);
                    System.out.println("Second Function");
                    allDoneLatch.countDown();
                } catch(Exception e) {}
            },
            () -> {
                try {
                    Thread.sleep(100);
                    System.out.println("First Function");
                    semaphore.release(); // 释放许可给Second线程
                    allDoneLatch.countDown();
                } catch(Exception e) {}
            }
        );
        executeAndWait(runnables);
        allDoneLatch.await();
        System.out.println("Main Execution Completed!");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:42:56