真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【JavaEE】單例模式(餓漢&懶漢)-創(chuàng)新互聯(lián)

目錄

我們一直強(qiáng)調(diào)成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)對(duì)于企業(yè)的重要性,如果您也覺得重要,那么就需要我們慎重對(duì)待,選擇一個(gè)安全靠譜的網(wǎng)站建設(shè)公司,企業(yè)網(wǎng)站我們建議是要么不做,要么就做好,讓網(wǎng)站能真正成為企業(yè)發(fā)展過程中的有力推手。專業(yè)網(wǎng)站制作公司不一定是大公司,創(chuàng)新互聯(lián)作為專業(yè)的網(wǎng)絡(luò)公司選擇我們就是放心。

前言:

單線程下的單例模式

餓漢模式

懶漢模式

多線程下的單例模式

懶漢模式的修改

1.加鎖

2.有條件的加鎖

3.解決內(nèi)存可見性和指令重排序


前言:

本片文章介紹設(shè)計(jì)模式中的一個(gè)模式——單例模式。

單例模式就是只允許創(chuàng)建出一個(gè)實(shí)例的類。比如之前在使用JDBC編程的時(shí)候的DataSource這個(gè)類,就可以使用單例模式。見這篇文章http://t.csdn.cn/uq1lR。

其中單例模式有很多種實(shí)現(xiàn)方法,這里只用懶漢模式和餓漢模式來實(shí)現(xiàn)單例模式。


單線程下的單例模式

單線程中,沒有線程安全問題,其代碼會(huì)簡單很多。

餓漢模式

餓漢模式體現(xiàn)出一個(gè)字——急。因?yàn)檫@個(gè)實(shí)例直接就是在類加載階段就被創(chuàng)建出來。

class SingletonHungry{

    // 用static修飾,這樣在類加載階段就有了這個(gè)實(shí)例
    private static SingletonHungry instance = new SingletonHungry();

    // 用靜態(tài)公開方法返回實(shí)例
    public static SingletonHungry getInstance() {
        return instance;
    }

    // 為了防止實(shí)例化多個(gè)對(duì)象,把構(gòu)造方法用private修飾
    private SingletonHungry(){};

}

public class SingletonTest1 {

    public static void main(String[] args) {

        SingletonHungry instance1 = SingletonHungry.getInstance();
        SingletonHungry instance2 = SingletonHungry.getInstance();
        System.out.println(instance1 == instance2);

        //SingletonHungry instance3 = new SingletonHungry();

    }

}


懶漢模式

懶漢模式突出一個(gè)字——懶。這個(gè)實(shí)例是只有調(diào)用獲取實(shí)例方法的時(shí)候才創(chuàng)建出來。

class SingletonLazy{
    private static SingletonLazy instance = null;

    // 只有在調(diào)用了該方法后才創(chuàng)造出了實(shí)例
    public static SingletonLazy getInstance() {
        // 如果已經(jīng)創(chuàng)建了該實(shí)例,就直接返回之前的實(shí)例
        if (instance == null) {
            instance =  new SingletonLazy();
        }
        return instance;
    }

    // 為了防止實(shí)例化多個(gè)對(duì)象,把構(gòu)造方法用private修飾
    private SingletonLazy(){}
}

public class SingletonTest2 {

    public static void main(String[] args) {

        SingletonLazy instance1 = SingletonLazy.getInstance();
        SingletonLazy instance2 = SingletonLazy.getInstance();
        System.out.println(instance1 == instance2);

        //SingletonLazy instance3 = new SingletonLazy();
    }

}

代碼結(jié)果如上。?


多線程下的單例模式

在上述代碼中,如果考慮多線程的話

餓漢模式?jīng)]有線程安全問題,它直接就是在類加載是創(chuàng)建出了一個(gè)實(shí)例,使用該實(shí)例也沒有其他修改的操作,直接返回即可。

懶漢模式是有線程安全問題。它又要判斷比較實(shí)例是否為null,又要?jiǎng)?chuàng)建一個(gè)實(shí)例,最后才返回實(shí)例。其中對(duì)于實(shí)例是由修改的操作的。只要有修改操作,就可能會(huì)有線程安全問題。如下圖:

懶漢模式的修改 1.加鎖

對(duì)于這種又有讀,又有寫的操作,保持原子性——加鎖即可。

public SingletonThread getInstance() {
        // 這里對(duì)于load cmp new這幾步加鎖,保持了其原子性
        synchronized (SingletonThread.class) {
            if (instance == null) {
                instance = new SingletonThread();
            }
        }
        return instance;
    }
2.有條件的加鎖

但是加鎖是一種開銷比較大的操作,上述加鎖操作并不是每次都要加鎖的。如果已經(jīng)創(chuàng)建了實(shí)例,直接返回實(shí)例即可。

public SingletonThread getInstance() {
        // 如果實(shí)例未被創(chuàng)建,用加鎖的方法創(chuàng)建實(shí)例
        // 如果創(chuàng)建,直接返回
        if (instance == null) {
            // 這里對(duì)于load cmp new這幾步加鎖,保持了其原子性
            synchronized (SingletonThread.class) {
                if (instance == null) {
                    instance = new SingletonThread();
                }
            }
        }
        return instance;
    }
3.解決內(nèi)存可見性和指令重排序

內(nèi)存可見性:因?yàn)閕nstance要讀取并修改,所以對(duì)于內(nèi)存可見性的問題也要預(yù)防。

指令重排序:

上面的new實(shí)例的指令又分為三個(gè)順序步驟:

①申請(qǐng)內(nèi)存空間

②調(diào)用構(gòu)造方法,實(shí)例化一個(gè)對(duì)象

③把內(nèi)存空間的地址賦值給這個(gè)對(duì)象

這幾步可能可能會(huì)變成①③②。單線程下沒有問題,但是多線程就會(huì)有問題了。

要想解決這兩個(gè)問題,使用volatile關(guān)鍵字修飾instance即可。

private volatile static SingletonThread instance = null;

完整的懶漢模式的線程安全代碼如下:

// 修改懶漢模式,使其線程安全
class SingletonThread {
    // 使用volatile解決內(nèi)存可見性和指令重排序問題
    private volatile static SingletonThread instance = null;

    public SingletonThread getInstance() {
        // 如果實(shí)例未被創(chuàng)建,用加鎖的方法創(chuàng)建實(shí)例
        // 如果創(chuàng)建,直接返回
        if (instance == null) {
            // 這里對(duì)于load cmp new這幾步加鎖,保持了其原子性
            synchronized (SingletonThread.class) {
                if (instance == null) {
                    instance = new SingletonThread();
                }
            }
        }
        return instance;
    }

}

有什么問題評(píng)論區(qū)指出。希望可以幫到你。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


當(dāng)前標(biāo)題:【JavaEE】單例模式(餓漢&懶漢)-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://weahome.cn/article/djicgd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部