簡體   English   中英

用於訪問易失性實例變量的局部變量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM