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
相关产品推荐
相关产品推荐

