| 1 |
一、final 变量
final 变量的语义:
只能被赋值一次。 这意味着变量的引用或值一旦确定,就不能被重新绑定。
确保可见性。 当对象的字段是 final 时,其他线程在看到这个对象引用时,一定能看到这些 final 字段的正确值(即构造函数中写入的值)。
1. 内存模型下的写屏障(Write Barrier)与读屏障(Read Barrier)
Java 编译器与 CPU 都会对指令进行重排序,以提高性能。而 final 的语义会插入一种特殊的内存屏障(Memory Barrier) 来阻止这种重排:
写屏障(Store Barrier):在构造函数中给 final 字段赋值后,JMM 会在该赋值之后插入一个写屏障,禁止该写操作与构造函数外部的“this 引用发布”重排。
1 2 3 4
| class A {<br /> final int x;<br /> A() {<br /> x = 42;
|
// StoreBarrier 插入于此,防止与 this 发布重排
读屏障(Load Barrier):当另一个线程读到一个包含 final 字段的对象时,JMM 保证先读 final 字段值,再读对象引用。这防止了读取到构造未完成的对象。
A a = new A(); // 构造函数执行完毕后才对外可见
这种设计保证了:
只要对象构造完成后才“发布”(即引用被其他线程可见),其他线程一定能看到构造函数中写入的所有 final 字段。
|