日出星辰

          各種創建單例模式的優缺點

          單例模式應用于一個類只有一個實例的情況,并且為其實例提供一個全局的訪問點。

          特點

          1.一個類只有一個實例

          2.自己創建這個實例

          3.整個系統只能用這個實例

          應用場景

          外部資源:每臺計算機有若干個打印機,但只能有一個PrinterSpooler,以避免兩個打印作業同時輸出到打印機。

          內部資源:大多數軟件都有一個(或多個)屬性文件存放系統配置,這樣的系統應該有一個對象管理這些屬性文件。

          實現方式

          1.餓漢式:單例實例在類裝載時就構建,急切初始化。(預先加載法)

          /**
           * 餓漢式(推薦)
           *
           */
          public class Singleton1 {
          
          	private Singleton1() {
          	}
          
          	public static Singleton1 instance = new Singleton1();
          
          	public Singleton1 getInstance() {
          		return instance;
          	}
          
          }

          優點 1.線程安全
          2.在類加載的同時已經創建好一個靜態對象,調用時反應速度快
          缺點 資源效率不高,可能getInstance()永遠不會執行到,但執行該類的其他靜態方法或者加載了該類(class.forName),那么這個實例仍然初始化

           

          2.懶漢式:單例實例在第一次被使用時構建,延遲初始化。

          class Singleton2 {
          	private Singleton2() {
          	}
          
          	public static Singleton2 instance = null;
          
          	public static Singleton2 getInstance() {
          		if (instance == null) {
                        //多個線程判斷instance都為null時,在執行new操作時多線程會出現重復情況
          			instance = new Singleton2();
          		}
          		return instance;
          	}
          }

          懶漢式在單個線程中沒有問題,但在多線程就可能會出現兩個或多個Singleton2實例情況,

          雖然后面實例化的Singleton2會覆蓋前面實例化的Singleton2,但最好避免這樣的情況。

          改進方式就是加鎖synchornized

          class Singleton3 {
          	private Singleton3() {
          	}
          
          	public static Singleton3 instance = null;
          
          	public static synchronized Singleton3 getInstance() {
          		if (instance == null) {
          			instance = new Singleton3();
          		}
          		return instance;
          	}
          }
          優點 資源利用率高,不執行getInstance()就不會被實例,可以執行該類的其他靜態方法
          缺點 第一次加載時不夠快,多線程使用不必要的同步開銷大


          3.雙重檢測

          class Singleton4 {
          	private Singleton4() {
          	}
          
          	public static Singleton4 instance = null;
          
          	public static Singleton4 getInstance() {
          		if (instance == null) {
          			synchronized (Singleton4.class) {
          				if (instance == null) {
          					instance = new Singleton4();
          				}
          			}
          		}
          		return instance;
          	}
          }

          優點 資源利用率高,不執行getInstance()就不被實例,可以執行該類其他靜態方法
          缺點 第一次加載時反應不快,由于java內存模型一些原因偶爾失敗

           

          4.靜態內部類

          class Singleton5 {
          	private Singleton5() {
          	}
          
          	private static class SingletonHelp {
          		static Singleton5 instance = new Singleton5();
          	}
          
          	public static Singleton5 getInstance() {
          		return SingletonHelp.instance;
          	}
          }

          優點 資源利用率高,不執行getInstance()不被實例,可以執行該類其他靜態方法
          缺點 第一次加載時反應不夠快

           

          總結:一般采用餓漢式(1),若對資源十分在意可以采用靜態內部類(4),不建議采用懶漢式及雙重檢測(2、3)

          另外

          對于第二種可以采用volatile方式

          volatile用更低的代價代替同步

          解釋:同步的代價主要有覆蓋范圍決定,如果可以降低同步的覆蓋范圍,可大幅提升性能。

          而volatile覆蓋范圍是變量級別的,因此同步代價很低。

          volatile原理:告訴處理器,不要將其放入工作內存,而是直接在主存操作。因此,當多處理器或多線程在訪問該變量時

          都將直接操作主存,這在本質上做到了變量共享。

          volation優勢:

          1.更大的程度吞吐量

          2.更少的代碼實現多線程

          3.程序伸縮性好

          4.比較好理解,無需太高的學習成本

          volatile不足:

          1.容易出問題

          2.比較難設計

          參考文獻

          http://yiminghe.iteye.com/blog/404334

          http://developer.51cto.com/art/201103/249322.htm

          posted on 2011-09-05 21:54 日出星辰 閱讀(3381) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 昌都县| 五寨县| 喀什市| 西贡区| 拉孜县| 长兴县| 长沙市| 双柏县| 贵德县| 东城区| 蚌埠市| 新乡市| 星子县| 苗栗县| 文山县| 绥阳县| 辉县市| 嫩江县| 石屏县| 宁安市| 奎屯市| 美姑县| 湖口县| 宜良县| 临漳县| 靖安县| 文昌市| 琼中| 盘山县| 临沧市| 平山县| 杨浦区| 鄄城县| 义马市| 西贡区| 东乌| 思茅市| 长顺县| 丰顺县| 南城县| 尚志市|