單例模式的主要用運場景寄锐,就是系統(tǒng)中需要一個對象實例存在勾扭。
1.最簡單的一種單例模式(餓漢模式)
public class Single{
public static Single instance = new Single()署拟;
private Single(){}
public static Single getInstance(){
return instance;
}
}
這種單例對象是Single類的靜態(tài)對象,在類裝載的時候就實例化了势似。不管有沒有人用拌夏,這個instance存在內存中,屬于用空間換取時間履因。
2.線程安全的單例模式簡單寫法(懶漢模式)
public class Single{
private static Single instance;
private Single(){}
public static synchronized Single getInstance(){
if(instance==null){
instance = new Single();
}
return instance;
}
這種線程安全的單例模式缺點障簿,是每次調用Single.getInstance()時都會進行synchronized同步消耗資源。由于懶漢模式的這個缺點所以產(chǎn)生了栅迄,DLC方式實現(xiàn)的單例站故。
3.DLC (Double Check Lock)fang方式
public class Single{
//volatile關鍵字的使用,如果不加volatile線程還是不安全的。導致原因由于類的加載機制
private volatile static Single instance = null;
private Single(){}
public static Single getInstance(){
//上來就判斷是不已經(jīng)不為空了西篓,如果已經(jīng)不為空了直接返回
if(instance==null){
/**1.A,B兩個線程instance==null,A先到同步代碼塊
* 2.則A先判斷new 出實例愈腾,同步代碼塊結束,B進入同步代碼塊
* 3.此時instance岂津!=null,返回A new的實例
*/
synchronized(Single.class){
if(instance==null){
instance = new Single();
}
}
}
return instance;
}
}
4.靜態(tài)內部類實現(xiàn)單例模式
public class Single{
private Single(){}
public static Single getInstance(){
return SingleInner.instance;
}
public static class SingleInner{
private static final Single instance = new Single();
}
}
第一次加載Single類時不會初始化instance虱黄,只有在調用getInstance時才會實例化instance,調用getInstance導致加載SingleInner類吮成。線程安全橱乱。
5.枚舉單例
public class Single{
public Single(){}
}
public enum SingleImpl{
INSTANCE;
private Single instance;
SingleImpl(){
instance = new Single();
}
public Single getInstance(){
return instance;
}
}
調用時使用SingleImpl.INSTANCE.getInstance()。優(yōu)點:線程安全赁豆,反序列化不會產(chǎn)生新的對象仅醇。