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

线程运行时memory.a修改值为何刷新至主存的技术咨询

线程变量刷新主内存的疑惑解答

问题描述

线程运行时,普通变量会被刷新至主内存?
据我理解,线程未停止时,memory.a应处于工作缓存(worker cache)中,示例代码如下:

public class SynchronizedMemory {
    // non-visible
    private int a = 0;
    public SynchronizedMemory(int a) {
        this.a = a;
    }

    private static void test2() throws InterruptedException {
        SynchronizedMemory memory = new SynchronizedMemory(1);
        Object lock = new Object();
        new Thread(() -> {
            System.out.println("thread1 start................");
            while (memory.a != -1) {
                // When I comment out this line, the thread never jumps out of the loop
                synchronized (lock){}
            }
            System.out.println("thread1 stop................");
        },"thread1").start();
        // wait for thread1 to run
        Thread.sleep(1000);
        new Thread(() -> {
            memory.a = -1;
            // keep the thread alive, prevent it from being completed and refresh the changes back to main memory
            while (true){}
        },"thread2").start();
    }
}

据我理解,thread2未停止时,memory.a的修改值应仍处于工作缓存中。但运行上述代码后,thread1退出循环并结束,这表明thread2中memory.a的修改值在thread2仍运行时就已刷新至主内存。请解释该现象。

问题解答

首先要纠正一个核心误解:Java内存模型(JMM)并没有规定线程只有结束时才会把工作缓存的变量刷回主内存。线程运行过程中,多种场景都会触发变量同步到主内存的操作,同时thread1的空同步块是让它能读到最新值的关键,具体拆解如下:

  1. thread2的写操作没有被限制在工作缓存
    memory.a = -1是普通写操作,JMM只保证最终会刷回主内存,但不限制时机。实际运行时,CPU缓存策略、JVM的内存调度、甚至系统内存压力,都可能导致这个修改立刻同步到主内存——线程持续运行不代表变量会一直锁在工作缓存里。

  2. thread1的空同步块强制了主内存读取
    while循环里的synchronized (lock){}空同步块,触发了JMM的happens-before规则:

    • 进入同步块前,thread1会失效自身工作缓存的对应数据,必须从主内存重新读取memory.a的值;
    • 退出同步块时,会把线程本地的修改刷回主内存(这里虽然没有修改,但规则依然生效)。
      正是这个同步操作,让thread1每次循环都会去主内存拉取最新的memory.a值,所以能及时看到thread2的修改并退出循环。
  3. 去掉同步块后循环无法退出的原因
    如果注释掉空同步块,JVM会做缓存优化和指令重排:由于循环内没有任何同步操作,JVM会判定memory.a的值不会被其他线程修改,直接把值缓存到CPU寄存器里,不再去主内存读取,导致thread1永远看不到thread2的修改,陷入死循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:43:25