synchronized退出临界区时强制将被修改的共享变量刷新回主内存,这是JMM规定的必须行为,非可选优化;JVM在monitorexit前执行release语义并插入StoreStore屏障,确保写操作不重排序到锁释放之后。

synchronized 退出代码块时,会强制将当前线程工作内存中所有被修改过的共享变量写回主内存——这不是可选优化,而是 Java 内存模型(JMM)规定的必须行为。
刷新动作由 JVM 自动触发,无需手动干预
只要线程执行完 synchronized 块或方法(无论正常结束还是抛出异常),JVM 都会在释放锁前插入 monitorexit 指令,并配套执行 release 语义:
- 把该线程在同步块内修改过的所有共享变量,逐个写入主内存(store + write)
- 确保这些写操作在锁真正释放前完成,构成对其他线程的可见前提
- 编译器和 CPU 不得将这些写操作重排序到锁释放之后
只刷“被修改过”的共享变量,且范围精准
刷新不是全量刷写,JVM 会做静态与运行时分析,仅处理实际被写入的共享变量:
- 局部变量、未被其他线程访问的字段、同步块内只读未改的字段,都不会被刷新
- 即使某个共享变量在块内被读取多次,只要没被赋新值,就不会触发写回
- 这种精细化识别避免了无谓的内存带宽消耗
刷新与锁释放严格绑定,构成 happens-before 关系
这个写回动作和锁释放共同构成了 JMM 中的同步次序保障:
立即学习“Java免费学习笔记(深入)”;
- 线程 A 在 synchronized 块内修改变量并退出 → 变量值刷入主内存 → 锁释放
- 线程 B 后续获取同一把锁进入 synchronized 块 → 清空本地副本 → 从主内存重读该变量
- A 的写与 B 的读之间形成明确的 happens-before 关系,B 一定能看到 A 的最新值
底层靠内存屏障保证指令顺序不被破坏
release 语义的实现依赖于 JVM 插入的内存屏障(Memory Barrier):
- 在 monitorexit 前插入 StoreStore 屏障,确保所有之前的写操作先于锁释放完成
- 防止 CPU 或 JIT 编译器把变量写操作延迟到锁释放之后
- 这是硬件级保障,不依赖线程调度或 OS 机制


















