這篇文章主要講述基於Java語言實現多線程的單例模式。java
對於一個軟件系統中的某些類而言,只有一個實例很重要,例如一個系統只能有一個窗口管理器或文件系統,一個系統只能有一個集市工具或ID生成器等等。在Windows操做系統中就只能打開一個任務管理器窗口,以下圖1所示。若是不使用機智對窗口對象進行惟一化,勢必會彈出多個窗口。若是這些窗口顯示的內容徹底一致,則是重複對象,浪費內存資源;若是這些窗口顯示的內容不一致,則意味着在某一瞬間系統有多個狀態,與實際不符合,這會給用戶帶來誤解,不知道哪個纔是真實的狀態。所以有時確保系統中某個對象的惟一性(即一個類只能有一個實例)很是重要。多線程
確保一個類只有一個實例,並提供一個全局訪問點來訪問這個惟一實例。工具
實例代碼spa
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
if(s1 == s2){
System.out.println("兩個對象是相同實例");
}
else{
System.out.println("兩個對象是不一樣實例");
}
}
}
複製代碼
運行截圖以下圖2操作系統
實例代碼線程
public class Singleton {
private Singleton() {
}
//靜態內部類
private static class SingletonHandler {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHandler.instance;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
System.out.println("兩個對象實例是否相同?");
System.out.println(s1 == s2);
}
}
複製代碼
運行截圖以下圖3code
餓漢式單例類在類加載時就將本身實例化,它的優勢在於無需考慮多個線程同時訪問的問題,能夠確保實例的惟一性;從調用速度和反應時間速度來說,因爲單例對象一開始就得以建立,所以要優於懶漢式單例。可是不管系統在運行時是否須要使用該單例對象,因爲在類加載時該對象就須要建立,所以從資源利用效率角度來說餓漢式單例不及懶漢式單例,並且在系統加載時因爲須要建立餓漢式單例對象,加載時間可能會比較長。cdn
懶漢式單例類在第一次使用時建立,無須一直佔用系統資源,實現了延遲加載,可是必需要處理多個線程同時訪問的問題,特別是當單例類做爲資源控制器,在實例化時必然涉及資源初始化,而資源初始化頗有可能耗費大量時間,這意味着出現多線程同時首次引用此類的概率比較大,須要經過同步化機制進行控制。對象
單例模式的主要優勢在於提供了對惟一實例的受控訪問並能夠節約系統資源;其主要缺點在於由於缺乏抽象層而難以擴展,且單例類職責太重。blog
單例模式適用狀況包括:系統只須要一個實例對象;客戶調用類的單個實例只容許使用一個公共訪問點。