小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

單例模式(3)

 頭號(hào)碼甲 2020-07-15

簡(jiǎn)介:

單例模式是一種簡(jiǎn)單的設(shè)計(jì)模式,但是要在程序設(shè)計(jì)中使用好單例模式,卻需要注意幾個(gè)地方。

單例模式意味著在整個(gè)系統(tǒng)中,單例類(lèi)只能有一個(gè)實(shí)例對(duì)象,且需要自行完成實(shí)例化,并始終對(duì)外提供同一個(gè)實(shí)例對(duì)象。

單例模式實(shí)現(xiàn)方式:

餓漢模式:

public class Singleton {
    //餓漢模式是最簡(jiǎn)單的實(shí)現(xiàn)方式,在類(lèi)加載時(shí)就創(chuàng)建單例類(lèi)對(duì)象
    private static final Singleton instance = new Singleton();

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton(){}

    public static Singleton newInstance(){
        //返回唯一的實(shí)例對(duì)象
        return instance;
    }
}

懶漢模式(單線程版):

public class Singleton {

    private static Singleton instance = null;

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton(){}

    public static Singleton newInstance(){
        // 在需要的時(shí)候才去創(chuàng)建的單例對(duì)象,如采羊例對(duì)象已經(jīng)創(chuàng)建,再次調(diào)用 ηewinstance()方法時(shí)
        // 將不會(huì)重新創(chuàng)建新的單例對(duì)象,而是直接返回之前創(chuàng)建的單例對(duì)象
        if (null == instance){
            instance = new Singleton();
        }
        //返回唯一的實(shí)例對(duì)象
        return instance;
    }
}

上述懶漢模式有延遲加載的意思,但是沒(méi)有考慮到多線程的情況,在多線程的場(chǎng)景中,出現(xiàn)多個(gè)線程同時(shí)調(diào)用newInstance方法創(chuàng)建單例對(duì)象,從而導(dǎo)致系統(tǒng)中出現(xiàn)多個(gè)單例類(lèi)的實(shí)例,顯然是不符合要求的。

懶漢模式(多線程加鎖版):

public class Singleton {

    private static Singleton instance = null;

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton(){}

    public static synchronized Singleton newInstance(){
        // 在需要的時(shí)候才去創(chuàng)建的單例對(duì)象,如采羊例對(duì)象已經(jīng)創(chuàng)建,再次調(diào)用 ηewinstance()方法時(shí)
        // 將不會(huì)重新創(chuàng)建新的單例對(duì)象,而是直接返回之前創(chuàng)建的單例對(duì)象
        if (null == instance){
            instance = new Singleton();
        }
        //返回唯一的實(shí)例對(duì)象
        return instance;
    }
}

上述加鎖設(shè)計(jì)雖然解決了多線程安全的問(wèn)題,但是單例在系統(tǒng)中只有一個(gè)實(shí)例,每次取實(shí)例都得進(jìn)行加鎖解鎖操作,這會(huì)成為系統(tǒng)的性能瓶頸。

懶漢模式(雙重檢測(cè)鎖方式):錯(cuò)誤實(shí)現(xiàn)

public class Singleton {

    private static Singleton instance = null;

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton() {
    }

    public static Singleton newInstance() {
        if (null == instance) {//第一次檢測(cè)
            synchronized (Singleton.class) {//加鎖
                if (null == instance) {//第二次檢測(cè)
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

由于指令重排優(yōu)化,可能會(huì)導(dǎo)致初始化單例對(duì)象和將該對(duì)象地址賦值給 instance 字段的順 序與上面 Java 代碼中書(shū) 寫(xiě) 的順序不同 。 例如,線程 A 在創(chuàng)建單例對(duì)象時(shí),在構(gòu)造方法被調(diào)用 之前,就為該對(duì)象分配了內(nèi)存空間并將對(duì)象的宇段設(shè)置為默認(rèn)值。此時(shí)線程 A 就可以將分配的內(nèi) 存地址賦值給 instance 宇段了,然而該對(duì)象可能還沒(méi)有初始化。線程 B 來(lái)調(diào)用 newInstance()方法,得 到的就 是未初始 化 完全 的單例對(duì)象,這就 會(huì)導(dǎo)致系統(tǒng)出 現(xiàn)異常行為 。

為了解決該問(wèn)題,我們可以使用 volatile關(guān)鍵字修飾 instance字段。 volatile關(guān)鍵字的一個(gè)語(yǔ)義就是禁止指令的重排序優(yōu)化,從而保證 instance 字段被初始化時(shí),單例對(duì)象己經(jīng)被完全初始化 。

懶漢模式(雙重檢測(cè)鎖方式 + volatile):

public class Singleton {

    private static volatile Singleton instance = null;

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton() {
    }

    public static Singleton newInstance() {
        if (null == instance) {//第一次檢測(cè)
            synchronized (Singleton.class) {//加鎖
                if (null == instance) {//第二次檢測(cè)
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

靜態(tài)內(nèi)部類(lèi)方式(推薦):

public class Singleton {

    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }

    //私有化構(gòu)造方法,防止外界創(chuàng)建對(duì)象
    private Singleton() {
    }

    public static Singleton newInstance() {
        return SingletonHolder.instance;
    }
}

熟悉 Java 類(lèi)加載機(jī)制 的讀者知道,當(dāng)?shù)?nbsp;一次訪 問(wèn)類(lèi)中的靜態(tài)字段時(shí),會(huì)觸發(fā)類(lèi)加載,并且同一個(gè)類(lèi)只加載一次。靜態(tài)內(nèi)部類(lèi)也是如此,類(lèi)加載過(guò)程由類(lèi)加載器負(fù)責(zé)加鎖,從而保證線程安全。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多