設計模式之單例DCL為什麼需要volatile

2021-10-07 13:26:30 字數 1228 閱讀 9319

單例模式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:分配物件的記憶體空間

instance(memory); // 2:初始化物件

instance = memory; // 3:設定instance指向剛分配的記憶體位址

以上步驟2與步驟3不存在資料依賴關係,而且無論重排前或者重排後程式的執行結果在單執行緒中沒有變化,因此這種重排優化是允許的。所以存在以下順序執**況:

memory = allocate(); // 1:分配物件的記憶體空間

instance = memory; // 3:設定instance指向剛分配的記憶體位址

instance(memory); // 2:初始化物件

如果執行順序為1.3.2,當a執行緒執行完1,3(此時還未完成物件初始化),這時b執行緒第一次判斷singleton == null,得到的結果未false,然後就會直接return乙個空的物件,繼而產生後續錯誤。

為什麼需要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 繫結...