單例模式:
確保某一個類只有一個實例,通過將類的實例化方法私有化來防止程序通過其他方式創建該類的實例,然後通過提供一個全局唯一獲取該類實例的方法來獲取類的實例。
若一個全局類的對象在多個地方被使用並且對象的狀態時全局變化的場景下,可以考慮使用單例模式。
單例模式常見的寫法有以下幾種:
/**
* 懶漢模式(線程安全)
* 1、構造方法私有化
* 2、定義一個私有靜態對線instance(靜態屬性或方法屬於類)
* 3、定義加鎖的靜態方法獲取該對線(加鎖且先檢查再執行)
* */
class LazySingleton{
private static LazySingleton instance;
private LazySingleton(){}
public static synchronized LazySingleton getInstance(){
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
/***
*餓漢模式(CLass Loader完成後該類的實例便存在於JVM中)
* 1、構造方法私有化
* 2、在類中直接定義全局的靜態對象的實例並初始化
* 3、提供靜態方法獲取該實例對象
*/
class HungrySingleton{
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return instance;
}
}
/**
* 靜態內部類(類的靜態內部類在JVM中是唯一)
* 1、構造方法私有化
* 2、在類中定義一個靜態內部類,並在內部類中完成對象實例的定義和初始化
* 3、定義獲取對象方法,並通過靜態內部類調用其單例對象
*/
class OuterSingleton{
private static class InnerSingleton{
private static final OuterSingleton INSTANCE = new OuterSingleton();
}
private OuterSingleton(){}
public static final OuterSingleton getInstance(){
return InnerSingleton.INSTANCE;
}
}
/**
* 雙重校驗鎖(在餓漢模式基礎上進一步優化)
* 1、構造方法私有化
* 2、在定義靜態對象時加volatile鎖來確保初始化時對象的唯一性
* 3、定義獲取對象實例方法,並在方法體中通過synchronized(Object)給單例類加鎖來保障操作的唯一性
* */
class DoubleCheckedLockingSingleton{
private volatile static DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton(){}
public static DoubleCheckedLockingSingleton getInstance(){
if(instance == null){
synchronized (DoubleCheckedLockingSingleton.class){
if(instance == null)
instance = new DoubleCheckedLockingSingleton();
}
}
return instance;
}
}