單例模式之懶漢模式(延遲載入)
阿新 • • 發佈:2019-02-12
什麼是延遲載入?延遲載入就是在呼叫get()方法時候建立,常見的方法就是在
get()中例項化。
看實現程式碼:
package test; public class MyObject { private static MyObject myObject; private MyObject() { } public static MyObject getInstance() { // 延遲載入 if (myObject != null) { } else { myObject = new MyObject(); } return myObject; } }
但是,這樣方式的延遲載入,在多執行緒的環境中,就會出現錯誤,很嚴重的錯誤。根本不能保證單例模式的實現。
因為在getInstance中,如果有多個執行緒同時計入getInstance,那麼就有可能new出多個MyObject。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
懶漢模式出現問題的解決方法:
①:將getInstance用synchronized修飾。
②:在getInstance方法中利用synchronized同步塊或者lock進行同步。
③:使用DCL雙檢查機制。
針對第三種方法,看一段程式碼:
package test; public class MyObject { private volatile static MyObject myObject; private MyObject() { } // 使用雙檢測機制來解決問題 // 即保證了不需要同步程式碼的非同步 // 又保證了單例的效果 public static MyObject getInstance() { try { if (myObject != null) { } else { // 模擬在建立物件之前做一些準備性的工作 Thread.sleep(3000); synchronized (MyObject.class) { if (myObject == null) { myObject = new MyObject(); } } } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } // 此版本的程式碼稱為: // 雙重檢查Double-Check Locking }
如有哪疏漏,還請指出,共同學習!