單例模式,屬於建立型別的一種常用的軟體設計模式。通過單例模式的方法建立的類在當前程序中只有乙個例項(根據需要,也有可能乙個執行緒中屬於單例,如:僅執行緒上下文內使用同乙個例項)
單例設計模式其實萬變不離其宗,總結為三個套路:
構造器私有化 --> 避免外部new構造器
提供私有的靜態屬性 --> 儲存物件的位址
提供公共的靜態方法 --> 獲取屬性
宣告私有靜態屬性時並初始化物件
優點:簡單,一般用在開啟執行緒之前先初始化,執行緒安全。
缺點:空間換時間。如果一直不使用會浪費空間
/**
* 餓漢單例模式
*/public
class
hungrysingleton
// 3. 對外提供公有的靜態方法獲取屬性值
public
static hungrysingleton getinstance()
}
宣告私有靜態屬性時並不馬上初始化物件,而是等到第一次呼叫時才去建立例項
優點:延遲載入,省空間。
缺點:第一次呼叫需要例項化物件,需要消耗時間並且容易引發執行緒問題(可以避免)
/**
* 懶漢單例模式
*/public
class
lazysingleton
// 3. 對外提供獲取例項的方法
public
static lazysingleton getinstance()
return instance;
}}
由於普通的懶漢式單例模式只適用於單執行緒的環境下。
在多執行緒的環境下使用會產生很多問題。於是就衍生出dcl單例模式(double checked locking)
/**
* dcl單例模式:懶漢式套路基礎上加入併發控制,保證在多執行緒環境下,對外存在乙個物件
*/public
class
doublecheckedlocking
// 3. 提供公有的靜態方法 --> 獲取屬性
public
static doublecheckedlocking getinstance()
}}return instance;
}}
getinstance方法中雙重判斷instance==null的原因:
dcl單例模式採用的是懶漢式單例。所以在第一次使用時才會建立例項。
此時在多執行緒的環境下可能會出現這樣的問題:
a執行緒和b執行緒同時去getinstance。
由於第一次instance例項還沒建立出來,所以a執行緒和b執行緒都得搶鎖
假設a執行緒搶到了鎖,那麼b執行緒只能等待鎖
a執行緒在完成物件的建立後獲得了instance例項,並釋放鎖,b執行緒獲得鎖
b執行緒再去判斷instance==null,不成立,因為a執行緒已經建立過了,所以直接return
但是dcl單例模式會出現一種問題:
這時假設a執行緒在初始化,還沒完成,就返回了位址,b在這時getinstance,直接走第一層instance==null
這時b執行緒獲得的單例就是還沒初始化完成的單例,會出現問題
所以這裡的instance加上了volatile,禁止指令重排
單例設計模式(餓漢單例設計模式 懶漢單例設計模式)
1.什麼是單例 單例的意思是乙個類永遠只存在乙個物件,不能建立多個物件。2.為什麼要用單例 開發中有很多的物件我們只需要乙個,例如虛擬機器物件,任務管理器物件 物件越多越佔記憶體,有時候只需要乙個物件就可以實現業務,單例可以節省記憶體空間。3.如何實現單例 單例的實現方式有 餓漢單例設計模式 通過類...
設計模式 單例設計模式
歷史 最早是建築學領域的模式,然後gof四人由其引申到編碼方面,總結了23種設計模式 設計模式 解決某一類事情最行之有效的方法 2.1 體現 餓漢式,保證物件的唯一性 class singleton 私有化建構函式禁止該類建立物件 private static singleton st new si...
設計模式 單例設計模式
單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項。即乙個類只有乙個物件例項 單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。單例設計模式 解決的問題 可以保...