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

如何仅用join、sleep、isAlive准确判定线程结束顺序(无锁/volatile)?

问题解答

首先明确:仅使用join()、sleep()、isAlive()确实可以100%准确判定两个线程的结束顺序,无需volatile、锁或同步机制。

原代码的问题

原代码的逻辑漏洞在于:在chickenThread.join()完成后立即检查eggThread.isAlive(),但此时eggThread可能刚好在chickenThread结束后极短时间内也终止了,导致isAlive()返回false,误判为chickenThread先结束(实际eggThread可能仅稍晚一点终止)。

正确实现方案

核心思路是持续等待直到至少一个线程终止,再通过isAlive()明确谁先结束,具体代码如下:

public class EggOrChicken {
    static Thread eggThread = eggVoice();
    static Thread chickenThread = chickenVoice();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("争论开始...");
        eggThread.start();
        chickenThread.start();
        
        // 循环等待直到至少一个线程结束
        while (eggThread.isAlive() && chickenThread.isAlive()) {
            // 短暂休眠避免空轮询消耗CPU
            Thread.sleep(10);
        }
        
        // 判断剩余存活的线程,确定结束顺序
        if (eggThread.isAlive()) {
            // egg线程仍在运行 → chicken先结束
            eggThread.join();
            System.out.println("先出现的是鸡!");
        } else {
            // chicken线程已结束 → egg先结束
            chickenThread.join();
            System.out.println("先出现的是蛋!");
        }
        
        System.out.println("争论结束!");
    }
    
    public static Thread eggVoice() {
        return new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("蛋!");
            }
        });
    }
    
    public static Thread chickenVoice() {
        return new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("鸡!");
            }
        });
    }
}

方案说明

  1. 循环等待:通过while循环持续检查两个线程的存活状态,直到其中一个终止。短暂的sleep(10)是为了避免无意义的空轮询,降低CPU占用。
  2. 可靠判定:循环退出时,必有一个线程已经终止。此时的isAlive()判断完全可靠——不会出现原代码中"线程刚终止但检查时机滞后"的误判情况。
  3. 收尾处理:调用剩余存活线程的join(),确保主线程等待所有子线程完成后再结束,保证程序执行的完整性。

内容的提问来源于stack exchange,提问作者Влад

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:43:17