單例模式

單例模式

簡單的可以理解在系統中只存在一個實例對象

適用場合:

一個對象需要頻繁創建和銷燬

  對象創建需要消耗一定的資源

一個對象即可滿足需要

單例模式優點: 節約內存,提高性能,避免了大對象頻繁創建的消耗

單例模式缺點:   不符合開閉原則,該類不支持拓展,當功能變化時修改代碼是必然的


單例的幾種實現方式: 

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)

}

}

學安卓的朋友看到這個有沒有覺得似曾相識,沒錯安卓裏面的服務就是這種形式。有興趣可以去看看安卓源碼

點評: 這種方式適合管理多個單例




 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章