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

Java多线程Race condition下打印结果不符合预期问题咨询

问题现象

提供的Java多线程代码运行时,始终打印"Mares do eat oats.",无法输出开发者预期的"Mares do not eat oats."。开发者原本的逻辑预期是:主线程给静态变量message赋目标值后休眠2000ms,醒来就会打印该目标值。

注:原代码片段中message = **"Mares do not eat oats.**";行的**是排版时误加的Markdown加粗标记,实际编译运行需要删除这两个符号,否则代码会报语法错误。

根因分析

问题出在多线程的执行时序和开发者的预期完全不符,和JVM内存可见性之类的底层机制无关,时间线非常明确:

  • T0时刻:主线程调用start()启动CorrectorThread子线程,子线程启动后第一时间执行sleep(1000),会在T0+1000ms的时间点醒来,执行修改message变量的逻辑。
  • 主线程启动子线程后没有任何等待,立刻给静态变量message赋值为"Mares do not eat oats.",随后执行sleep(2000),会在T0+2000ms的时间点醒来执行打印逻辑。
  • T0+1000ms时刻:子线程比主线程早1000ms结束休眠,直接把全局共享的message变量值覆盖为"Mares do eat oats.",执行完后子线程直接退出。
  • T0+2000ms时刻:主线程休眠结束读取message变量时,拿到的已经是被子线程覆盖过的值,自然打印不出预期内容。

另外要注意:靠Thread.sleep()控制多线程执行顺序本身就是非常不可靠的写法,不同机器的CPU负载、线程调度策略不同,休眠唤醒的时间点存在误差,很容易出现偶现的时序问题。

修复方案

根据实际业务需求选对应方案即可:

  • 如果仅要满足当前打印预期:将CorrectorThread中的休眠时长从1000ms调整为3000ms以上,保证子线程修改message的动作发生在主线程打印之后即可。
  • 如果要稳定控制线程执行顺序:使用Thread.join()、显式锁、CountDownLatch等线程同步工具明确约束执行顺序,不要依赖休眠时长判断时序。
  • 如果子线程修改message的逻辑本身是冗余的:直接删除子线程中给message赋值的语句即可。

参考可运行的修复代码:

public class BadThreads {

    static String message;

    private static class CorrectorThread
        extends Thread {

        public void run() {
            try {
                sleep(3000); 
            } catch (InterruptedException e) {
                // 不要空吞中断异常,恢复中断标记是最佳实践
                Thread.currentThread().interrupt();
            }
            message = "Mares do eat oats."; 
        }
    }

    public static void main(String args[])
        throws InterruptedException {
        CorrectorThread correctorThread = new CorrectorThread();
        correctorThread.start();
        message = "Mares do not eat oats.";
        Thread.sleep(2000);
        System.out.println(message);
        // 等待子线程执行完成,避免程序直接退出
        correctorThread.join();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:01:03