設計模式2:單例模式
單例模式
確保一個類中只有一個例項,自行例項化並向整個系統提供這個例項,這個類被稱為單例類,它提供全域性的訪問方法
特點
在類中只有一個例項,並提供一個靜態的getInstacne()方法用於外界唯一訪問這個例項
防止在外部對其例項化,建構函式私有化
在單例類內部定義了一個Singleton型別的靜態物件,作為外部共享的唯一例項
舉例
windows作業系統中的工作管理員,回收站等,在系統中都只有一個例項,是典型的的單例模式
五種實現方式
餓漢式(執行緒安全)
顧名思義,既然是惡漢,肯定是飢不擇食啦,所以不管三七二十一,在類載入的時候就把例項給創建出來咯
//餓漢式 public class SingletonDemo2 { private static SingletonDemo2 instance = new SingletonDemo2(); //私有化構造器 private SingletonDemo2(){ } public static SingletonDemo2 getInstance(){ return instance; } }
優點:不用考慮執行緒同步問題
缺點:如果getInstance方法,則會造成資源浪費
懶漢式(執行緒安全,延時載入)
建立例項這麼麻煩的事情。。當然要拖到最後一刻啦,等需要用到例項的時候再建立
//懶漢式 public class SingletonDemo1 { private static SingletonDemo1 instance; //私有化構造器 private SingletonDemo1(){ } public static synchronized SingletonDemo1 getInstance(){ if(instance == null){ instance = new SingletonDemo1(); } return instance; } }
優點:延遲載入,資源利用率提高
缺點:同步造成併發效率低
雙重加鎖機制
在之前的懶漢式中,它的缺點非常明顯,為了保證在多執行緒的工作下能正常工作,它進行了同步,下一個執行緒想要獲取物件,就必須等待上一個執行緒釋放鎖之後,才可以繼續執行。但是百分之99.9的情況下都是不需要同步的,所以它的效率是非常低的,於是我們進行優化,避免整個方法被鎖,只對需要鎖的程式碼部分加鎖,可以提高執行效率。
//雙重校驗鎖 public class SingletonDemo3 { private volatile static SingletonDemo3 instance; private SingletonDemo3(){ } public static SingletonDemo3 getInstance(){ if(instance == null){ synchronized (SingletonDemo3.class) { if(instance == null){ instance = new SingletonDemo3(); } } } return instance; } }
靜態內部類實現
//靜態內部類
public class SingletonDemo4 {
private static class SingletonClassInstance {
private static final SingletonDemo4 instance = new SingletonDemo4();
}
private SingletonDemo4(){
}
public static SingletonDemo4 getInstance(){
return SingletonClassInstance.instance;
}
}
外部類沒有static屬性,則不會像餓漢式那樣立即載入物件。
只有真正呼叫getInstance(),才會載入靜態內部類。載入類時是執行緒 安全的。 instance是static final型別,保證了記憶體中只有這樣一個例項存在,而且只能被賦值一次,從而保證了執行緒安全性.
兼備了併發高效呼叫和延遲載入的優勢!
列舉
public enum SingletonDemo5 {
/**
* 定義一個列舉的元素,它就代表了Singleton的一個例項。
*/
INSTANCE;
/**
* 單例可以有自己的操作
*/
public void singletonOperation(){
//功能處理
}
}
•優點:
–實現簡單
–列舉本身就是單例模式。由JVM從根本上提供保障!避免通過反射和反序列化的漏洞!
•缺點:
–無延遲載入
總結
篇中對單例模式進行了簡單介紹,同時介紹了它的五種典型的實現方式