(一)單例模式
要點:(1)各個類都隻有一個實例。(2)它必須自行創建這個唯一實例。(3)它必須自行向其他對象提供該實例。
本質:控制實例的數量。
應用場景:線程池、緩存、日志對象、對話框、打印機、顯卡的驅動程序對象等。
(二)單例模式主要分為:懶漢式單例、餓漢式單例兩種。
1. 懶漢式(延遲加載法):以時間換空間
public class Singleton {
//1.收回外部實例化Singleton類的權限
private Singleton(){};
//3.聲明一個靜態對象來保存實例
private static Singleton single = null;
//2.主動向外部提供獲取該實例的方法
public static Singleton getInstance()
{
//4.判斷實例是否已實例化
if(single == null)
{
//5.未實例化則實例化
single = new Singleton();
}
return single;
}
}
優點:資源利用率高,不執行getInstance就不會被實例。
缺點:線程不安全,並發環境下可能出現多個實例。
改進方案:
public class Singleton {
//1.收回外部實例化Singleton類的權限
private Singleton(){};
//3.聲明一個靜態對象來保存實例
private static Singleton single = null;
//2.主動向外部提供獲取該實例的方法(加上synchronized鎖達到線程安全)
public static synchronized Singleton getInstance()
{
//4.判斷實例是否已實例化
if(single == null)
{
//5.未實例化則實例化
single = new Singleton();
}
return single;
}
}
缺點:synchronized的使用增加瞭不必要的資源開銷。
2. 餓漢式(預先加載法):以空間換時間
public class Singleton {
//1.收回外部實例化Singleton類的權限
private Singleton(){};
//3.運行即初始化實例
private static Singleton single = new Singleton();
//2.主動向外部提供獲取該實例的方法
public static Singleton getInstance()
{
return single;
}
}
優點:線程安全;運行即進行初始化,所以調用實例速度快。
缺點:資源利用率不高,可能存在永遠用不到的實例。
測試:
public class main {
public static void main(String []args)
{
Singleton single1 = Singleton.getInstance(); //獲取實例1
Singleton single2 = Singleton.getInstance(); //獲取實例2
if(single1 == single2) //判斷兩個實例是否是同一實例
{
System.out.print("同一實例");
}
else
{
System.out.print("不同實例");
}
}
}
運行結果:同一實例