Double Check Lock


Double Check Lock(DCL)


通過單例模式生產類是程序員必會,它有很多寫法,其中的懶漢式,及延遲生成類,應使用雙重檢查,否則就會出現生成多例:

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

以上代碼看起來似乎以及完美了,但是其實還有漏洞。如下:

實例化一個對象要分為三個步驟:

  1. 分配內存空間
  2. 初始化對象
  3. 將內存空間的地址賦值給對應的引用

但是由於重排序的緣故,步驟2、3可能會發生重排序,其過程如下:

  1. 分配內存空間
  2. 將內存空間的地址賦值給對應的引用
  3. 初始化對象

如果2、3發生了重排序就會導致第二個判斷會出錯,singleton != null,但是它其實僅僅只是一個地址而已,此時對象還沒有被初始化,所以return的singleton對象是一個沒有被初始化的對象。

解決方法是在一處加上關鍵字:

private volatile static Singleton singleton;       //1

這樣就保證了變量singleton的可見性,使得程序能到達到我們的預期。


參考資料:

http://cmsblogs.com/?p=2161


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM