happens-before在锁定规则中的核心作用是确保后续成功加锁的线程一定能看见前一线程解锁前的所有修改;它通过unlock与lock配对的内存屏障实现“释放-获取”语义,保障临界区修改对下一个进入者100%可见。

锁定规则中的 happens-before 关系,核心作用不是“让解锁立刻被看到”,而是确保“一旦后续线程成功加锁,就一定能看见解锁前的所有修改”。它靠的是逻辑约束 + 内存屏障,而非强制实时同步。
解锁操作本身不广播,但它的“完成”构成可见性起点
一个线程执行 synchronized 块结束时的 unlock,并非向全系统发通知。但它在语义上标记了一个关键节点:该线程对共享变量的所有写入,此时必须对主内存可见。JVM 会在 unlock 指令前后插入内存屏障(如 StoreStore + StoreLoad),强制把缓存中脏数据刷回主内存,并禁止编译器/CPU 把 unlock 后的操作重排到它前面。
- unlock 不是“发送动作”,而是“确认提交”的信号
- 没有其他线程在等这个 unlock,但只要之后有线程对同一把锁执行 lock,happens-before 规则就立即生效
- 可见性不是“unlock 后马上可见”,而是“下一个 lock 开始时一定可见”
加锁动作触发强制读取与重排序限制
后续线程执行 lock 时,JVM 同样插入内存屏障(如 LoadLoad + LoadStore),强制从主内存重新加载变量值,并禁止把 lock 前的读写操作重排到它后面。这保证了:一旦 lock 成功返回,线程看到的一定是 unlock 之后、主内存中已刷新的最新状态。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- lock 不是“等待更新”,而是“主动拉取+清空本地缓存视图”
- 即使 unlock 和 lock 之间隔了几毫秒、甚至跨 CPU 核心,屏障机制仍能保障一致性
- 这种“释放-获取”配对,语义上等价于一次完整的内存同步事件
实际效果:临界区修改对下一个进入者 100% 可见
比如线程 A 在 synchronized 块中设置 data = 100; ready = true;,线程 B 稍后用同一把锁进入。由于 A 的 unlock happens-before B 的 lock,B 进入后读到的 ready 一定是 true,且此时读到的 data 也一定是 100——哪怕 data 是普通变量,不加 volatile 也没问题。
立即学习“Java免费学习笔记(深入)”;
- 不需要每个字段都声明 volatile,锁规则天然提供批量可见性保障
- 可见性范围覆盖整个临界区内所有写操作,不限于锁对象本身
- 这是 synchronized 比单纯用 volatile 更强的地方:它同时解决原子性、可见性、有序性
它不追求“即时”,但严守“一旦发生,就完整可靠”。这就是 happens-before 在锁定规则中落地的方式。

















