JMM保障多线程可见性的方案还包括final字段、显式Lock、原子类及线程启停happens-before规则:final字段在正确构造后对其他线程可见;ReentrantLock加锁/解锁具备与synchronized相同的内存语义;AtomicXXX类通过volatile+CAS保证可见性与原子性;thread.start()前的写操作对新线程可见,thread.join()后子线程的写操作对主线程可见。

Java 内存模型(JMM)中保障多线程可见性的方案,除了 volatile 和 synchronized,还有以下几种明确有效的方式:
final 字段的初始化保证
被 final 修饰的字段,在构造器中完成赋值后,对其他线程天然可见。JMM 通过 final 规则 保证:只要对象已正确构造(即没有 this 逃逸),其他线程看到该对象时,一定能看到 final 字段的正确值。
- 适用于不可变对象设计,如包装类、配置类、单例中的 final 实例字段
- 注意:仅对 final 引用本身及其直接字段生效;若 final 引用指向可变对象,该对象内部状态仍需额外同步
显式 Lock(ReentrantLock 等)
java.util.concurrent.locks.Lock 接口的实现类(如 ReentrantLock)在加锁和解锁时,遵循与 synchronized 相同的 JMM 语义:
- 成功获取锁(lock())时,会强制从主内存重新读取共享变量(清空本地工作内存)
- 释放锁(unlock())前,会将修改后的共享变量刷新回主内存
- 本质是通过 AQS 内部的 volatile state 变量 + 内存屏障实现可见性保障
原子类(AtomicXXX)
java.util.concurrent.atomic 包下的原子类(如 AtomicInteger、AtomicReference)底层基于 CAS + volatile 实现:
立即学习“Java免费学习笔记(深入)”;
- 所有 get/set 方法都具备 volatile 读/写语义,保证可见性
- compareAndSet、getAndIncrement 等复合操作还具备原子性
- 适合计数器、状态标志、无锁数据结构等场景
线程启动与终止的 happens-before 关系
虽然不依赖关键字或类库,但 JMM 明确规定了两类隐式可见性保障:
- 线程启动规则:主线程调用 thread.start() 之前的所有写操作,对新线程的 run() 方法可见
- 线程终止规则:子线程执行完毕后,其所有写操作对调用 thread.join() 的线程可见
- 这类保障无需显式同步,但依赖正确的线程生命周期控制


















