1)單例模式的定義:
在整個應用中,保證一個類只有一個實例,它提供了一個可以訪問到它自己的全局訪問點(靜態方法)。
2)單例模式的優缺點:
優點:
1、提供了對唯一實例的受控訪問;
2、Java中頻繁創建和銷毀類對象都會占用一部分系統資源,使用單例模式可以提高性能;
3、允許可變數量的實例;
缺點:
1、單例模式中,沒有抽象層,所以對於單例類的擴展並不方便;
2、單例類的職責過重,在一定程度上違背了“單一職責原則”;
3、濫用單例將帶來一些負面問題,如為了節省資源將數據庫連接池對象設計為的單例類,可能會導致共享連接池對象的程序過多而出現連接池溢出;如果實例化的對象長時間不被利用,系統會認為是垃圾而被回收,這將導致對象狀態的丟失;
3)簡單介紹幾種單例,單例模式中有區分了懶漢式和餓漢式,懶漢式主要是用時間來換空間,餓漢式則是用空間來換時間。餓漢式是線程安全的,懶漢式是非線程安全的,如果要實現懶漢式的非線程安全,則可以再訪問點添加synchronized關鍵字聲明即可。在其他的一些項目中還使用了雙重檢測枷鎖機制。
1、懶漢單例,存在線程不安全問題,如啟動多線程,同時調用入口方法獲取實例時不能正常工作:
//懶漢單例,線程不安全,當啟動多線程,同時獲取多個實例時會報錯 private static PostContentForResponse instance = null; private PostContentForResponse() {} public static PostContentForResponse getInstance() { if(instance == null) { instance = new PostContentForResponse(); } return instance; }
懶漢模式也提供一種解決同步調用時不能正常工作的方法,使用synchronized聲明訪問點,但是工作效率低
private static PostContentForResponse instance = null; private PostContentForResponse() {} public static synchronized PostContentForResponse getInstance() { if(instance == null) { instance = new PostContentForResponse(); } return instance; }
2、餓漢單例,這種方式基於classloder機制避免了多線程的同步問題,但是instance在類裝載時就實例化,雖然導致類裝載的原因有很多種,
在單例模式中大多數都是調用getInstance方法,但是也不能確定有其他的方法(或者其他靜態方法)導致類裝載,這是初始化的instance
顯然沒有達到lazy loading的效果。
private static PostContentForResponse instance = new PostContentForResonse(); private PostContentForResponse() {} public static PostContentForResponse getInstance() { return instance; }
3、靜態內部類,跟餓漢模式有點類似,只是在類裝載的時候,SingletonHolder並沒有被主動使用,只有顯式調用getInstance方法是,才會調用裝載SingletoHolder類,從而實例化instance,既實現了線程安全,又避免了同步帶來的性能影響。
private static class SingletonHolder { private static final PostContentForResponse INSTANCE = new PostContentForResponse(); } private PostContentForResponse() {} public static final PostContentForResponse getInstance() { return SingletonHolder.INSTANCE; }