假设一个线程A执行writer方法,另一个线程执行reader方法。由于构造函数中利用1和2之间没有数据依赖性,1和2可以重排序,先执行了2,这个时间引用对象referenceDemo是个没有完全初始化的对象,而当线程B去读取该对象时就会出错。尽管依然满足了final域写重排序规则:在引用对象对所有线程可见时,其final域已经完全初始化乐成。但是,引用对象“this”逸出,该代码依然存在线程安全的题目。
使用 final 的限制条件和局限性
当声明一个 final 成员时,必须在构造函数退出前设置它的值。
public class MyClass {
private final int myField = 1;
public MyClass() {
...
}
}
复制代码
或者
public class MyClass {
private final int myField;
public MyClass() {
...
myField = 1;
...
}
}
复制代码
将指向对象的成员声明为 final 只能将该引用设为不可变的,而非所指的对象。
下面的方法仍然可以修改该 list。