1、概念:單例模式保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點
2、單例模式(singleton),定義了乙個getinstance操作,允許客戶訪問它的唯一例項。getinstance是乙個靜態方法,主要負責建立自己的唯一例項。
class singleton
public static singleton getinstance()
return instance;
}}
3、單例模式的特性:
4、單例模式的應用:
為何要用單例模式?
對於系統中的某些類來說,只有乙個例項很重要,例如,乙個系統只能有乙個視窗管理器或者檔案系統;乙個系統只能有乙個計時工具或者id(序號)生成器
比如印表機、執行緒池、對話方塊等被設定為單例模式
5、單例模式的分類:
1)懶漢式:需要用時才去建立物件
2)餓漢式:建立類的例項時就去建立物件
6、懶漢式:
//懶漢式單例類.在第一次呼叫的時候例項化自己
public class singleton
private static singleton single=null;
//靜態工廠方法
public static singleton getinstance()
return single;
} }
將構造方法限定為private,避免了類在外部被例項化,在同乙個虛擬機器範圍內,singleton的唯一例項只能通過getinstance()方法訪問。但是以上懶漢式單例的實現沒有考慮執行緒安全的問題,它是執行緒不安全的,併發環境下可能出現多個singleton例項,要實現執行緒安全,有以下幾種方式,都是對getinstance這個方法改造,保證了懶漢式單例的執行緒安全:
(1)在getinstance方法上加同步關鍵字synchronized,但影響執行效率,乙個執行緒呼叫,其他執行緒則需等待
public static synchronized singleton getinstance()
return single;
}
(2)加雙重檢查鎖,比較高效
public static singleton getinstance()
}
}
return singleton;
}
需要特別注意的是一定要加volatile關鍵字,這樣才能保證在記憶體中訪問到的是最新值,從而有效的做雙重判斷,保證只有乙個instance物件
(3)靜態內部類
public class singleton
public synchronized static singleton getinstance()
private singleton()
}
利用靜態內部類,某個執行緒在呼叫該方法時會建立乙個例項化物件
7、餓漢式:
//餓漢式單例類.在類初始化時,已經自行例項化
public class singleton1
private static final singleton1 single = new singleton1();
//靜態工廠方法
public static singleton1 getinstance()
}
餓漢式在類建立的同時就已經建立好乙個靜態的物件供系統使用,以後不再改變,所以天生是執行緒安全的
以上三種方法的區別:
(1)在方法上加了同步,雖然執行緒安全,但是每次都要同步,會影響效能,畢竟99%的情況下是不需要同步的
(2)在getinstance中做了兩次null檢查,確保了只有第一次呼叫單例的時候才會做同步,執行緒安全,同時避免了每次都要同步的效能損耗
(3)利用classloader的機制來保證初始化是只有乙個執行緒,所以也是執行緒安全的,沒有效能損耗
8、懶漢式和餓漢式的區別:
餓漢式就是類一旦載入,就把單例初始化完成,保證getinstance的時候,單例已經是存在的了
而懶漢式比較懶,只有當呼叫getinstance的時候,才回去初始化這個單例
(1)執行緒安全:
餓漢式是執行緒安全的,可以直接用於多執行緒而不會出現問題
懶漢式本身是非執行緒安全的,為了實現執行緒安全有以上幾種方法
(2)資源載入和效能:
餓漢式在類建立的同時就例項化乙個靜態物件出來,不管之後會不會使用這個單例,都會佔據一定的記憶體,但是相應的,在第一次呼叫時速度也會更快,因為其資源已經初始化完成
懶漢式會延遲載入,在第一次使用該單例的時候才會例項化物件出來,第一次呼叫時要做初始化,如果要做的工作比較多,效能上會有些延遲,之後就和餓漢式一樣了
9、指令重排序
懶漢式的雙重檢查版本的單例模式,一定是執行緒安全的嗎? 不一定,因為在jvm的編譯過程中會存在指令重排序的問題
(1)在建立乙個物件的時候,包含三個過程:
對於singleton = new singleton(),這不是原子操作,在jvm中包含的三個過程
(2)但是,由於jvm會進行指令重排序,所以上面的第二步和第三步的順序不能保證,最終的執行順序可能是1-2-3,也可能是1-3-2,如果是1-3-2,則在3執行完畢,2未執行之前,被另乙個執行緒搶占了,這是instance已經是非null了,但是沒有初始化,所以這個執行緒會直接返回instance,然後使用,肯定報錯
(3)解決方法:把 singleton宣告成volatile,改進後的懶漢式執行緒安全(雙重檢查鎖)的**如下:
public class singleton }}
return ourinstance;
}
10、單例模式在jdk8原始碼中的使用
(1)runtime類部分原始碼如下:
/餓漢式單例設計模式
public class runtime
private runtime()
//省略很多行
}
設計模式解析之單例模式
單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。單例模式是一種常見的設計模式,在計算機系統中,執行緒池 快取 日誌物件 對話方塊 印表機 資料庫操作 顯示卡的驅動程式常被設計成單例。單例模式分3種 懶漢式單例 餓漢式單例 登記式單例。單例模式有以下3個特點 1 只能有乙個例項...
設計模式 單例設計模式
歷史 最早是建築學領域的模式,然後gof四人由其引申到編碼方面,總結了23種設計模式 設計模式 解決某一類事情最行之有效的方法 2.1 體現 餓漢式,保證物件的唯一性 class singleton 私有化建構函式禁止該類建立物件 private static singleton st new si...
設計模式 單例設計模式
單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項。即乙個類只有乙個物件例項 單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。單例設計模式 解決的問題 可以保...