溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

雙重校驗(yàn)鎖實(shí)現(xiàn)單例模式(對象單例,線程安全)

發(fā)布時間:2020-07-30 21:13:25 來源:網(wǎng)絡(luò) 閱讀:1023 作者:不倒翁88 欄目:編程語言

雙重校驗(yàn)鎖實(shí)現(xiàn)單例模式:

public class Singleton {

    //采用volatile修飾
    private volatile static Singleton singleton;

    //構(gòu)造方法私有化
    private Singleton(){}

    //雙重校驗(yàn)鎖
    public static Singleton getInstance(){
        //先判斷對象是否已經(jīng)實(shí)例過,沒有實(shí)例化過才進(jìn)入加鎖代碼
        if(singleton == null){
            //類對象加鎖
            synchronized(Singleton.class){
                //再次判斷
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

注意:singleton 采用 volatile 修飾是很有必要的,因?yàn)?singleton = new Singleton() 這句話可以分為三步:

  1. 為 singleton 分配內(nèi)存空間;
  2. 初始化 singleton;
  3. 將 singleton 指向分配的內(nèi)存空間。
    但是由于JVM具有指令重排的特性,執(zhí)行順序有可能變成 1-3-2。 指令重排在單線程下不會出現(xiàn)問題,但是在多線程下會導(dǎo)致一個線程獲得一個未初始化的實(shí)例。例如:線程T1執(zhí)行了1和3,此時T2調(diào)用 getInstance() 后發(fā)現(xiàn) singleton 不為空,因此返回 singleton, 但是此時的 singleton 還沒有被初始化。
    使用 volatile 會禁止JVM指令重排,從而保證在多線程下也能正常執(zhí)行
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI