[英]Local variable used to access volatile instance variable
創建對已經作為成員字段保留的靜態volatile變量的本地引用的目的或價值是什么? 這里這段代碼是從java.util.Scanner的JDK 6b14 這里 。
class Scanner {
private static volatile Pattern linePattern;
...
private static Pattern linePattern() {
Pattern lp = linePattern;
if (lp == null)
linePattern = lp = Pattern.compile("...");
return lp;
}
...
}
Java教程 :“對於聲明為volatile的所有變量(包括long和double變量),讀寫都是原子的。任何對volatile變量的寫操作都會與該變量的后續讀取建立先發生后關系。”
這意味着讀取對Pattern對象的引用不會因更改而中途失敗。 volatile關鍵字應該完全保護這類訪問,所以我不是說重復的局部變量是為了確保返回有效值。
同樣,可以在成員字段上完成延遲初始化,而無需中間局部變量:
if (linePattern == null) linePattern = Pattern.compile("...");
如此處和此處所示,這似乎是字節碼優化。 使用局部變量將產生較小的字節碼(較少的指令)以及較少的對實際值的訪問(這是昂貴的易失性讀取)。 但是他們還沒有使用最終變量優化,因此我對得出這個結論持懷疑態度。
延遲初始化 ,即將工作延遲到真正需要的時候。
即使在檢查和返回之間將靜態變量設置為NULL,也可以確保返回的值不為NULL。
同時,這是一個不同步的惰性初始化,需要時可以重新初始化;)。
這樣可以“加快”速度。 訪問volatile
變量很昂貴。 通過將其分配給堆棧變量並訪問它,使用可以避免這種開銷
對於volatile
字段, linePattern
可能會在不同的行之間改變。 將引用復制到局部變量可確保您不會出現不一致的狀態。 例如,如果您寫過
if (linePattern == null)
linePattern = Pattern.compile("...");
那么在執行Pattern.compile
時, linePattern
可能已不再為null。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.