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

Java多线程:如何让第三个Color线程在任意前两线程结束后启动?

你想用BlockingQueue确实没必要,这个需求用基础线程API或者CountDownLatch就能轻松实现,属于过度设计了。下面给两种靠谱的实现方式:

方法1:直接检查线程状态(最直观)

修改Main方法,启动前两个线程后,循环等待任意一个线程终止,满足条件就启动第三个线程:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Color color1 = new Color("Blue");
        Color color2 = new Color("Red");
        Color color3 = new Color("White");

        // 将Runnable包装为Thread实例
        Thread tBlue = new Thread(color1);
        Thread tRed = new Thread(color2);
        Thread tWhite = new Thread(color3);

        // 立即启动Blue和Red线程
        tBlue.start();
        tRed.start();

        // 循环等待任意一个前置线程结束(避免CPU空转,加短睡眠)
        while (tBlue.isAlive() && tRed.isAlive()) {
            Thread.sleep(100);
        }

        // 启动White线程
        tWhite.start();

        // 可选:等待所有线程执行完毕,避免程序提前退出
        tBlue.join();
        tRed.join();
        tWhite.join();
    }
}

class Color implements Runnable{
    private String color ;

    public Color(String color) {
        this.color = color;
    }

    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(color);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

方法2:用CountDownLatch(更优雅,无轮询)

用CountDownLatch实现信号通知式等待,避免轮询线程状态,代码更简洁:

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // 初始化计数为1,只要任意一个前置线程完成就触发信号
        CountDownLatch finishSignal = new CountDownLatch(1);

        // 给Blue和Red线程传入信号量,White线程不需要
        Color color1 = new Color("Blue", finishSignal);
        Color color2 = new Color("Red", finishSignal);
        Color color3 = new Color("White");

        Thread tBlue = new Thread(color1);
        Thread tRed = new Thread(color2);
        Thread tWhite = new Thread(color3);

        // 立即启动前两个线程
        tBlue.start();
        tRed.start();

        // 等待任意一个前置线程完成(计数归0)
        finishSignal.await();

        // 启动White线程
        tWhite.start();

        // 等待所有线程执行完毕
        tBlue.join();
        tRed.join();
        tWhite.join();
    }
}

class Color implements Runnable{
    private String color ;
    private CountDownLatch finishSignal;

    // 给前置线程用的构造方法
    public Color(String color, CountDownLatch finishSignal) {
        this.color = color;
        this.finishSignal = finishSignal;
    }

    // 给White线程用的构造方法
    public Color(String color) {
        this.color = color;
    }

    public void run() {
        try {
            for (int i = 0; i < 3; i++) {
                System.out.println(color);
                Thread.sleep(300);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 前置线程完成后触发信号(即使两个线程都调用,也只会把计数从1减到0,后续调用无效)
            if (finishSignal != null) {
                finishSignal.countDown();
            }
        }
    }
}

补充说明

  • BlockingQueue主要用于生产者-消费者的线程间数据传递,这里只是简单的线程完成等待触发,用它完全没必要,属于过度设计。
  • 两种方法都能满足需求:前两个线程立即启动,第三个线程在任意前置线程完成后启动,最终三个线程各自输出对应颜色3次。

内容的提问来源于stack exchange,提问作者Mr.Cake

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:50:10