摘要:
本文首先概述了單例模式產生動機,揭示了單例模式的本質和應用場景。緊接著,我們給出了單例模式在單執行緒環境下的兩種經典實現:餓漢式 和懶漢式,但是餓漢式是執行緒安全的,而懶漢式是非執行緒安全的。在多執行緒環境下,我們特別介紹了五種方式來在多執行緒環境下建立執行緒安全的單例,即分別使用synchronized方法、synchronized塊、靜態內部類、雙重檢查模式 和threadlocal 來實現懶漢式單例,並總結出實現效率高且執行緒安全的懶漢式單例所需要注意的事項。
單例模式(singleton),也叫單子模式,是一種常用的設計模式。在應用這個模式時,單例物件的類必須保證只有乙個例項存在。許多時候,整個系統只需要擁有乙個的全域性物件,這樣有利於我們協調系統整體的行為。比如在某個伺服器程式中,該伺服器的配置資訊存放在乙個檔案中,這些配置資料由乙個單例物件統一讀取,然後服務程序中的其他物件再通過這個單例物件獲取這些配置資訊,顯然,這種方式簡化了在複雜環境下的配置管理。
特別地,在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。事實上,這些應用都或多或少具有資源管理器的功能。例如,每台計算機可以有若干個印表機,但只能有乙個 printer spooler(單例) ,以避免兩個列印作業同時輸出到印表機中。再比如,每台計算機可以有若干通訊埠,系統應當集中 (單例)管理這些通訊埠,以避免乙個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。
綜上所述,單例模式就是為確保乙個類只有乙個例項,並為整個系統提供乙個全域性訪問點的一種方法。
單例模式應該是23種設計模式中最簡單的一種模式了,下面我們從單例模式的定義、型別、結構和使用要素四個方面來介紹它。
定義: 確保乙個類只有乙個例項,並為整個系統提供乙個全域性訪問點 (向整個系統提供這個例項)。
型別: 建立型模式
結構:
三要素:
在介紹單執行緒環境中單例模式的兩種經典實現之前,我們有必要先解釋一下 立即載入 和延遲載入 兩個概念。
立即載入 : 在類載入初始化的時候就主動建立例項;
延遲載入: 等到真正使用的時候才去建立例項,不用時不去主動建立。
在單執行緒環境下,單例模式根據例項化物件時機的不同,有兩種經典的實現:一種是 餓漢式單例(立即載入),一種是 懶漢式單例(延遲載入)。餓漢式單例在單例類被載入時候,就例項化乙個物件並交給自己的引用;而懶漢式單例只有在真正使用的時候才會例項化乙個物件並交給自己的引用。**示例分別如下:
餓漢式單例:
// 餓漢式單例
public
class
singleton1
// 以自己例項為返回值的靜態的公有方法,靜態工廠方法
public
static singleton1 getsingleton1()
}
我們知道,類載入的方式是按需載入,且載入一次。。因此,在上述單例類被載入時,就會例項化乙個物件並交給自己的引用,供系統使用;而且,由於這個類在整個生命週期中只會被載入一次,因此只會建立乙個例項,即能夠充分保證單例。
懶漢式單例:
// 懶漢式單例
public
class
singleton2
// 以自己例項為返回值的靜態的公有方法,靜態工廠方法
public
static singleton2 getsingleton2()
return singleton2;
}}
我們從懶漢式單例可以看到,單例例項被延遲載入,即只有在真正使用的時候才會例項化乙個物件並交給自己的引用。
總之,從速度和反應時間角度來講,餓漢式(又稱立即載入)要好一些;從資源利用效率上說,懶漢式(又稱延遲載入)要好一些。
我們從單例模式的定義和實現,可以知道單例模式具有以下幾個優點:
在記憶體中只有乙個物件,節省記憶體空間;
避免頻繁的建立銷毀物件,可以提高效能;
避免對共享資源的多重占用,簡化訪問;
為整個系統提供乙個全域性訪問點。
由於單例模式具有以上優點,並且形式上比較簡單,所以是日常開發中用的比較多的一種設計模式,其核心在於為整個系統提供乙個唯一的例項,其應用場景包括但不僅限於以下幾種:
在使用單例模式時,我們必須使用單例類提供的公有工廠方法得到單例物件,而不應該使用反射來建立,否則將會例項化乙個新物件。此外,在多執行緒環境下使用單例模式時,應特別注意執行緒安全問題,我在下文會重點講到這一點。
單例模式理解
單例模式 三要素 1 私有的構造方法 2 私有的靜態的例項物件 3 公共的靜態的提供訪問方法 根據單例模式的建立時機可以將其分為兩種型別 1 懶漢模式 在系統初始化時不會做初始化,會在什麼時候使用到時做初始化操作。public class ehanmoshi private static lanha...
理解單例模式
對單例模式這一部落格的理解。在多執行緒時不能正常工作,因為沒有加synchronized 所以嚴格來說不能算是單例模式。public class singleton public static singleton getinstance return instance public class si...
理解設計模式 單例模式
定義 確保要建立的類只有乙個例項 對於頻繁建立的物件,可以省略其建立時間,同時可以減輕gc的壓力 避免對共享資源的多重占用 使用場景 單例模式寫法很多,這裡列舉以下三種 1 最簡單的寫法 使用列舉物件public enum singletonenum使用列舉還可以避免反射獲取類的私有構造方法從而建立...