在java中,為了保證final域的正确使用,對重排序進行了一些限制
1.在構造函數内對一個final域的寫入,與随後把這個被構造對象的引用指派給一個引用
變量,這兩個操作之間不能重排序
2.初次讀一個包含final域的對象的引用,與随後初次讀這個final域,這兩個操作之間不能
重排序
有了這個限制,如下A,B線程分别調用writer和reader方法時,可以保證final變量被初始化了
public class FinalReferenceEscapeExample {
final int i;
static FinalReferenceEscapeExample obj;
public FinalReferenceEscapeExample () {
i = 1;
}
public static void writer() {
obj = new FinalReferenceEscapeExample ();
}
public static void reader() {
if (obj != null) {
int temp = obj.i;
}
}
}
final保證了fianl域的初始化一定在給obj複制前執行
要防止溢出:如
public class FinalReferenceEscapeExample {
final int i;
static FinalReferenceEscapeExample obj;
public FinalReferenceEscapeExample () {
i = 1;
obj = this;
}
public static void writer() {
new FinalReferenceEscapeExample ();
}
public static void reader() {
if (obj != null) {
int temp = obj.i;
}
}
}
i = 1;
obj = this;這個兩句是可能被重排的,可能B執行reader并不能讀到i的初始值