final域写操作在构造函数末尾插入StoreStore屏障,确保final值在对象引用发布前写入主内存;读操作在首次读引用后、首次读final域前插入LoadLoad屏障,保证读到正确初始化值。

Java 内存模型中,final 域的写操作在构造函数末尾隐式插入一个 StoreStore 屏障;final 域的读操作在首次读取对象引用后、首次读取该 final 域前,隐式插入一个 LoadLoad 屏障。
final 写:StoreStore 屏障保障初始化完成可见性
编译器在构造函数中对 final 域赋值完成后、对象引用被发布(如赋值给静态变量或共享字段)之前,会插入 StoreStore 屏障。它的作用是:
- 禁止把 final 域的写操作重排序到构造函数之外
- 确保该写操作(如
j = 2)一定在对象引用对外可见前完成并刷出到主内存 - 避免其他线程看到“半初始化”的对象——即引用已可见,但 final 值尚未写入
final 读:LoadLoad 屏障保障读取顺序与值正确性
当线程第一次读取某个对象引用(如 obj),紧接着第一次访问其 final 域(如 obj.j)时,JVM 会在两者之间插入 LoadLoad 屏障。它的作用是:
- 禁止处理器将 final 域的读操作重排序到对象引用读取之前
- 确保线程能读到该 final 域在构造期间写入的正确值,而非默认值(如 0、null)
- 配合写端的 StoreStore,共同构成“发布-消费”安全链,实现安全的无锁对象发布
注意:不是所有读写都加屏障,仅限“初次”场景
这两个屏障只在特定语义下触发:
立即学习“Java免费学习笔记(深入)”;
- 写屏障仅作用于构造函数内 final 域的**首次写入**,且必须发生在对象引用发布前
- 读屏障仅作用于线程**首次读引用 + 首次读该 final 域**的组合,后续读取不触发
- 普通域、非 final 字段、或 final 域在构造外的修改(非法)均不受此保护
这种设计让 final 在不牺牲性能的前提下,为不可变对象提供了轻量级、编译器与硬件协同的可见性与有序性保证。


















