首先是單例模式的內容:
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例
單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。在計算機系統中,線程池、緩存、日誌對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每臺計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。總之,選擇單例模式就是爲了避免不一致狀態,避免政出多頭
一:懶漢式單例(線程安全版)
package SingleTon;
public class Singleton {
static Singleton singleton1,singleton2;;
private static Singleton instance;
String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
public static void main(String[] args){
singleton1 = Singleton.getInstance();
singleton1.setName("1");
singleton2= Singleton.getInstance();
singleton2.setName("2");
System.out.println(singleton1.getName());
if(singleton1 == singleton2) System.out.println("兩次獲取相同");
}
}
結果:
2
兩次獲取相同
(事實上,通過Java反射機制是能夠實例化構造方法爲private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認爲反射機制不存在。)
二:餓漢式
package SingleTon;
public class HungrySingleton {
//加載慢,使用快
private HungrySingleton(){};
//已經創建好
private static HungrySingleton hSingleton = new HungrySingleton();
//靜態工廠方法
public static HungrySingleton getInstance(){
return hSingleton;
}
public static void main(String[] args){
HungrySingleton a = HungrySingleton.getInstance();
}
}
由於在類創建的時候就已經創建好靜態對象,以後不再改變,所以是線程安全的。