1. 可見性
2. 禁止指令重排序
2.1 dcl疑問解釋class
factory
public
static factory getinstance()
}}return factory;
}}
synchronized **快中的非空判斷
這裡做判斷是防止在初始化factory的時候,有兩個執行緒進入,其中乙個執行緒進入建立factory例項,另外乙個執行緒blocked在synchronized處。當第乙個進入的執行緒解鎖後,另外乙個執行緒進入,這時factory已經建立成功,不需要再建立,所以做一次非空判斷。
為static變數factory加上 volatile 關鍵字的原理
物件建立例項分為兩部分:
(1) 通過 new 在堆中分配記憶體
(2) 呼叫 物件的構造方法初始化分配的記憶體
這裡分三步:factory =
newfactory()
;
(1) 通過new 在堆中為factory物件分配記憶體。
(2) 呼叫 factory的無參構造方法初始化分配的記憶體。
(3) 使用建立的factory為factory賦值。
如果factory沒有使用volatile修飾,則有可能物件的初始化指令在 factory 靜態變數賦值這條指令之後,這時如果有其他執行緒獲取factory變數,拿到的是乙個未初始化的物件,使用起來有風險。
如果加上 volatile,則由上面 volatile的作用中的禁止指令重排序得知,會在為 factory變數賦值之後加上乙個寫屏障,禁止factory賦值之前的指令排到facotry賦值命令之前。也就不會出現物件沒有初始化,就為factory賦值,也就不會出現另外乙個執行緒拿到沒有初始化完成的factory物件。
2.2 上面懶漢式單例的另外一種實現
使用靜態內部類,在獲取的時候才建立 factory例項。class
factory
private
static
class
singlefactory
public
static factory getinstance()
}
Volatile關鍵字理解
物理角度 由於計算機的儲存裝置和cpu的運算速度有幾個數量級的差距,所以現代計算機系統加入一層速度接近 cpu的快取記憶體 cache 但cache帶來乙個問題 快取一致性問題 在多處理器系統中,每個處理器機油自己的cache 工作記憶體 又共享同一主記憶體。舉例 當程式在執行過程中,會將運算需要的...
volatile關鍵字理解
public class test read start new thread update start 執行結果 執行緒update會一直執行,執行緒read不會執行,執 況一直如此。原因分析 執行緒read,無法感知init value的變化,因為執行緒read中讀到的init value值一直...
如何理解volatile關鍵字
暫時由於查了好多網路上的資料都沒有具體的說明,有範圍也很大沒有看懂,後面如果理解有錯再修改。1.全域性共享變數非volatile 我是這樣理解的,對於多執行緒中,多個執行緒啟動時,部分先啟動的執行緒會把全域性變數拷貝乙個副本到自己的執行緒棧,有的則是啟動 還沒有read load變數到自己的本地棧空...