單例

關(guān)于單例在多線程中,鎖的作用是防止創(chuàng)建多個(gè)是實(shí)例。
由于理解不深刻,最近我走進(jìn)了一個(gè)怪圈,竟然想成了防止多線程,操作同一個(gè)實(shí)例。(算了 感覺最近有點(diǎn)懵逼)
其實(shí)如果同時(shí)操作同一個(gè)實(shí)例需要同步,在相應(yīng)的方法加鎖就可以解決。

主要可以分為兩大類
懶漢式:指全局的單例實(shí)例在第一次被使用時(shí)構(gòu)建。
餓漢式:指全局的單例實(shí)例在類裝載時(shí)構(gòu)建。

幾種實(shí)現(xiàn)方式

1、靜態(tài)內(nèi)部類

public class A1 {

    private static class A1Holder {
        private static final A1 INSTANCE = new A1();
    }

    public static final A1 getInstance() {
        return A1Holder.INSTANCE;
    }

    private A1() {
    }
}

由于內(nèi)部類延遲加載,只有在調(diào)用getInstance時(shí),才會初始化實(shí)例
從內(nèi)部類來看是餓漢式,從外部來看是懶漢式

2、創(chuàng)建靜態(tài)的實(shí)例,靜態(tài)實(shí)例會在裝載時(shí)構(gòu)建。再創(chuàng)建靜態(tài)方法獲取實(shí)例,這樣就能保證實(shí)例唯一。(餓漢式)

public class A2 {

    private static final A2 ourInstance = new A2();

    public static A2 getInstance() {
        return ourInstance;
    }

    private A2() {
    }

}

缺點(diǎn):
1、可能由于初始化的太早,造成資源的浪費(fèi)。
2、如果初始化本身依賴于一些其他數(shù)據(jù),那么也就很難保證其他數(shù)據(jù)會在它初始化之前準(zhǔn)備好。
適合: 使用單例占用資源少,不需要其他初始化數(shù)據(jù)。

3、枚舉

public enum A3 {
    
    INSTANCE;
    
    public void fun1(){
        
    }
    
}
//  call   A3.INSTANCE.fun1();

(Android官網(wǎng)不建議使用enums,占用內(nèi)存多)

4、調(diào)用時(shí)創(chuàng)建,同步方法(懶漢式)

public class B1 {

    private static B1 instance;

    public static synchronized B1 getInstance(){//執(zhí)行效率低
        if(instance ==null){
            instance = new B1();
        }
        return instance;
    }

    private B1(){}

}

4.2、雙重檢查

public class B2 { //Double check

    private static B2 instance;

    public static B2 getInstance() {
        if (instance == null) { // instance 可能為中間態(tài)
            synchronized (B2.class) {
                if (instance == null) {
                    instance = new B2(); //instance 可能創(chuàng)建內(nèi)存空間,但為形成實(shí)例
                }
            }
        }
        return instance;
    }

    private B2() {
    }

}

4.3 雙重檢查 + volatile

public class B3 {

    private volatile static B3 instance; //volatile 寫操作時(shí) 不能讀

    public static B3 getInstance() {
        if (instance == null) {
            synchronized (B3.class) {
                if (instance == null) {
                    instance = new B3(); //instance 可能創(chuàng)建內(nèi)存空間,但為形成實(shí)例
                }
            }
        }
        return instance;
    }

    private B3() {
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容