1. 程式人生 > >單例模式中的雙重檢查加鎖

單例模式中的雙重檢查加鎖

本文是在學習單例模式時遇到的問題

在多執行緒中,如何防止單例模式被多次例項,當然是要加鎖啦。但是加了鎖就意味著執行緒雖然安全,但效率肯定會變低,這是,就出現了雙重檢查加鎖。但看到這段程式碼,我又有疑問了?

public class Singleton {
    private volatile static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        //先檢查例項是否存在,如果不存在才進入下面的同步塊
        if(instance == null){
            //同步塊,執行緒安全的建立例項
            synchronized (Singleton.class) {
                //再次檢查例項是否存在,如果不存在才真正的建立例項
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

一開始我是看不懂的,為什麼會有再次檢查例項是否存在呢,上面不是檢查了一次了嗎?

原來,我忘了,這是在多執行緒下執行的,當兩個執行緒同時建立例項時,如果沒有第二次空判斷,那麼第一個執行緒肯定沒問題,建立成功,但是當第二個執行緒也建立時,因為同時執行,它們都可以通過第一重instance == null 的判斷。然後由於synchronized,只能進入等待,如果沒有第二次判斷,第二個執行緒就可以繼續再建立例項了。

單例模式中的懶漢式是和餓漢式

懶漢是和餓漢式區分非常簡單,懶漢式,顧名思義,懶載入,在類載入的時候就已經在內部例項化了。餓漢式就相反,等到在用到的時候再載入。