單例模式dcl實現
pulic class
singleton
//類的內部宣告變數
//volatile防止指令重排
private
static
volatile singleton singleton;
//對外暴露乙個靜態方法,當呼叫該方法時,才去建立例項(singleton)
//加入雙重檢查,解決執行緒安全問題,同時支援lazy loading,同時保證了效率
//推薦使用
public
static singleton getinstance()
}}return singleton;
}}
不加volatile會有什麼問題?
程式執行過程中, 為了效能考慮, 編譯器和cpu可能會對指令重新排序。
在極少數的情況下,下面語句會發生指令重排
singleton = new singleton();以上語句經過編譯後,可分為以下三步(偽**)
memory = allocate(); // 1:分配物件的記憶體空間以上步驟2與步驟3不存在資料依賴關係,而且無論重排前或者重排後程式的執行結果在單執行緒中沒有變化,因此這種重排優化是允許的。所以存在以下順序執**況:instance(memory); // 2:初始化物件
instance = memory; // 3:設定instance指向剛分配的記憶體位址
memory = allocate(); // 1:分配物件的記憶體空間如果執行順序為1.3.2,當a執行緒執行完1,3(此時還未完成物件初始化),這時b執行緒第一次判斷singleton == null,得到的結果未false,然後就會直接return乙個空的物件,繼而產生後續錯誤。instance = memory; // 3:設定instance指向剛分配的記憶體位址
instance(memory); // 2:初始化物件
為什麼需要volatile?
volatile可實現禁止指令重排,防止上述情況發生。
DCL單例模式為什麼還需要加volatile
目錄 dcl是什麼 dcl存在什麼問題 volatile如何解決dcl存在的問題 dcl 即雙重驗證加鎖 什麼是雙重驗證加鎖,看下面 public class person public static person getinstance return person 不難看出,就是在單例模式下獲取例...
dcl單例模式
有時候我們需要對外呈現只有乙個物件,簡單來說就是講物件私有化,像資料那樣,只能通過get方法得到。這裡使用doublechecking來進行該操作,即在get方法裡面加入兩個判斷該物件是否為空,同時為了避免指令重排導致執行緒獲得空物件,加入volatile,而且私有化構造器。public class...
DCL單例模式
單例模式 外部不能new物件,類的內部有且只有乙個物件,僅僅用乙個靜態方法與外界進行互動。public class doublecheckedlocking 外部只能通過這個get方法和此物件進行交流 public static doublecheckedlocking getinstance 繫結...