單例模式(Singleton Pattern)
0. 定義
(1) 系統(tǒng)只需要一個(gè)實(shí)例對(duì)象,如系統(tǒng)要求提供一個(gè)唯一的序列號(hào)生成器或資源管理器,或者需要考慮資源消耗太大而只允許創(chuàng)建一個(gè)對(duì)象。
(2) 客戶調(diào)用類的單個(gè)實(shí)例只允許使用一個(gè)公共訪問點(diǎn),除了該公共訪問點(diǎn),不能通過其他途徑訪問該實(shí)例。
確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類稱為單例類,它提供全局訪問的方法。單例模式是一種對(duì)象創(chuàng)建型模式。
1. 使用場(chǎng)景:
為了節(jié)約系統(tǒng)資源,有時(shí)需要確保系統(tǒng)中某個(gè)類只有唯一一個(gè)實(shí)例,當(dāng)這個(gè)唯一實(shí)例創(chuàng)建成功之后,我們無法再創(chuàng)建一個(gè)同類型的其他對(duì)象,所有的操作都只能基于這個(gè)唯一實(shí)例。
2. 舉個(gè)例子
class TaskManager
{
private static TaskManager tm = null; //靜態(tài)對(duì)象,作為外部共享的唯一實(shí)例。
private TaskManager() {……} //初始化窗口,private防止外部實(shí)例化
public void displayProcesses() {……} //顯示進(jìn)程
public void displayServices() {……} //顯示服務(wù)
public static TaskManager getInstance()
{
if (tm == null)
{
tm = new TaskManager();
}
return tm;
}
……
}
3. 多線程導(dǎo)致單例模式失效解決方法
- 餓漢式單例類
class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() { }
public static EagerSingleton getInstance() {
return instance;
}
}
在類被加載時(shí)就將自己實(shí)例化,無須考慮多線程訪問問題,可以確保實(shí)例的唯一性,但系統(tǒng)加載時(shí)間可能會(huì)比較長(zhǎng)
- 懶漢式單例類
class LazySingleton {
private volatile static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() {
//第一重判斷
if (instance == null) {
//鎖定代碼塊
synchronized (LazySingleton.class) {
//第二重判斷
if (instance == null) {
instance = new LazySingleton(); //創(chuàng)建單例實(shí)例
}
}
}
return instance;
}
}
實(shí)現(xiàn)了延遲加載,需要通過雙重檢查鎖定等機(jī)制進(jìn)行控制,這將導(dǎo)致系統(tǒng)性能受到一定影響。
- IoDH
通過使用IoDH,我們既可以實(shí)現(xiàn)延遲加載,又可以保證線程安全,不影響系統(tǒng)性能,不失為一種最好的Java語言單例模式實(shí)現(xiàn)方式(其缺點(diǎn)是與編程語言本身的特性相關(guān),很多面向?qū)ο笳Z言不支持IoDH)。
//Initialization on Demand Holder
class Singleton {
private Singleton() {
}
private static class HolderClass {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return HolderClass.instance;
}
public static void main(String args[]) {
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
System.out.println(s1==s2);
}
}
簡(jiǎn)單工程模式(Simple Factory Pattern)
定義:
定義一個(gè)工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類。因?yàn)樵诤?jiǎn)單工廠模式中用于創(chuàng)建實(shí)例的方法是靜態(tài)(static)方法,因此簡(jiǎn)單工廠模式又被稱為靜態(tài)工廠方法(Static Factory Method)模式,它屬于類創(chuàng)建型模式。使用場(chǎng)景:
(1) 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少,由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過復(fù)雜。
(2) 客戶端只知道傳入工廠類的參數(shù),對(duì)于如何創(chuàng)建對(duì)象并不關(guān)心。