被Volatile修飾後的DCL(double check locking)懶漢式單例模式
阿新 • • 發佈:2021-01-06
單例模式核心思想: 構造器私有,提供static外部建立方法
-
DCL懶漢式(安全,執行緒同步): 每次建立物件的時候先對物件判斷一下,沒有這個物件的時候我再給你 這個物件,有的話就不給了,雙鎖結構(方法上鎖,內容上鎖)
class LazySingle{ //使用volatile保證變數的一致性 private volatile static LazySingle lazySingle=null; public static LazySingle getInstance(){ //為了解決程式碼中的效率問題,只有s為空的時候,才進入 synchronized的程式碼段,大大減少了機率
- volatile保證變數唯一性的原因,是因為
new lazySingle()
不是一個原子操作。可能在A執行緒的時候進行132步,B執行緒進行123步。當A執行緒正在把物件指向記憶體空間時,B執行緒執行到第一個判斷空的時候,發現為false,因為物件指向了S記憶體,此時B執行緒可能會認為lazySingle已經被建立(line6),就直接返回了instance例項,但此時instance並沒有初始化完全。所以上層在使用的時候會出現問題。 - 同步程式碼塊外加判空條件,這個判空是為了程式效率,全掉後導致效率變低。因為去掉之後,不管instance是否已經初始化,都會進行
synchronized
操作,而synchronized
是一個重操作消耗效能。加上之後,如果已經初始化直接返回結果,不會進行synchronized
操作。 - 同步程式碼塊里加判空條件,為了防止多執行緒情況下多次初始化例項,假設兩個執行緒a和b都通過了第一個判空條件。此時假設a先獲得鎖,進入
synchronized
的程式碼塊,初始化instance,a釋放鎖。接著b獲得鎖,進入synchronized
的程式碼塊,也直接初始化instance,導致初始化了兩次,加上判空就可以防止這種情況發生