單例模式
簡單的可以理解在系統中只存在一個實例對象
適用場合:
一個對象需要頻繁創建和銷燬
對象創建需要消耗一定的資源
一個對象即可滿足需要
單例模式優點: 節約內存,提高性能,避免了大對象頻繁創建的消耗
單例模式缺點: 不符合開閉原則,該類不支持拓展,當功能變化時修改代碼是必然的
單例的幾種實現方式:
1、 餓漢式
public class Sington {
public static Sington sington = new Sington();
public static Sington getInstance() { return sington};
private Sington() {}
}
案例: Runtime.getRuntime();
點評: 簡單粗暴的實現方式
2、 懶漢式
public class Sington {
public static Sington sington = null;
public static Sington getInstance() {
if(sington == null)
sington = new Sington();
return sington;
}
private Sington() {}
}
點評:在單線程中是非常合適的但不適合多線程使用,那麼怎麼解決多線程問題呢,沒錯,可以使用synchronized關鍵字,具體實現如下:
public class Sington {
public static Sington sington = null;
public static synchronized Sington getInstance() {
if(sington == null)
sington = new Sington();
return sington;
}
private Sington() {}
}
細心的朋友會發現這樣確實解決了多線程問題,但是每次調用該方法時都使用了同步機制,這多少會有些性能問題,因爲其實我們只需要在第一次調用該方法時保證同步即可,那就是接下來的第三種方式。
3、 DCL (double check lock) (推薦使用)
public class Sington {
public static Sington sington = null;
public static Sington getInstance() {
if(sington == null) {// 該處判斷避免不必要的同步
sychronized(Sington.class) {
if(sington == null) {// 該處判斷保證sington爲null時才創建
sington = new Sington();
}
}
}
return sington;
}
private Sington() {}
}
點評: 這種實現方式是比較推薦的一種實現方式,在很多地方被使用,比如我們常用的ImageLoad圖片框架便採用了這種實現方式。
注意: 其實在多線程特別複雜的環境下,該方式也不完全能保證正確。這個有機會再講
4、 靜態內部類單例模式 (推薦使用)
public class Sington {
private Sington() {}
public static Sington getInstance() {
return SingtonHolder.sington;
}
private static class SingtonHolder {
private static final Sington sington = new Sington();
}
}
點評: 第一次加載Sington類時並不會實例化Singon,只有在第一次調用getInstance方法時纔會創建,因爲調用該方法虛擬機就會主動加載SingtonHolder類。這種方式幾乎完美,既保證唯一性又是線程安全的5、 藉助容器實現單例模式
public class SingtonManger {
private static HashMap<String,Object> objMap = new HashMap(String,Object);
private SingtonManger(){};
public static void registerService(String key, Object obj) {
if(!objMap.contains(key))
objMap.put(key,obj);
}
public static Object getService(String key) {
return objMap.get(key)
}
}
學安卓的朋友看到這個有沒有覺得似曾相識,沒錯安卓裏面的服務就是這種形式。有興趣可以去看看安卓源碼
點評: 這種方式適合管理多個單例