亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

設(shè)計(jì)模式:單例模式 (關(guān)于餓漢式和懶漢式)

Darkgel / 1574人閱讀

摘要:在寫單例模式的代碼之前,我們先簡單了解一下兩個(gè)知識點(diǎn),關(guān)于類的加載順序和關(guān)鍵字。懶漢和餓漢在程序編寫上,一般將單例模式分為兩種,分別是餓漢式和懶漢式,餓漢式在類加載時(shí)就完成了初始化,所以類加載比較慢,但獲取對象的速度快。

定義

單例模式是比較常見的一種設(shè)計(jì)模式,目的是保證一個(gè)類只能有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,避免頻繁創(chuàng)建對象,節(jié)約內(nèi)存。

單例模式的應(yīng)用場景很多,

比如我們電腦的操作系統(tǒng)的回收站就是一個(gè)很好的單例模式應(yīng)用,電腦上的文件、視頻、音樂等被刪除后都會進(jìn)入到回收站中;還有計(jì)算機(jī)中的打印機(jī)也是采用單例模式設(shè)計(jì)的,一個(gè)系統(tǒng)中可以存在多個(gè)打印任務(wù),但是只能有一個(gè)正在工作的任務(wù);Web頁面的計(jì)數(shù)器也是用單例模式實(shí)現(xiàn)的,可以不用把每次刷新都記錄到數(shù)據(jù)庫中。

通過回味這些應(yīng)用場景,我們對單例模式的核心思想也就有了更清晰的認(rèn)識,下面就開始用代碼來實(shí)現(xiàn)。

在寫單例模式的代碼之前,我們先簡單了解一下兩個(gè)知識點(diǎn),關(guān)于類的加載順序和static關(guān)鍵字。

類加載順序

類加載(classLoader)機(jī)制一般遵從下面的加載順序

如果類還沒有被加載:

先執(zhí)行父類的靜態(tài)代碼塊和靜態(tài)變量初始化,靜態(tài)代碼塊和靜態(tài)變量的執(zhí)行順序跟代碼中出現(xiàn)的順序有關(guān)。

執(zhí)行子類的靜態(tài)代碼塊和靜態(tài)變量初始化。

執(zhí)行父類的實(shí)例變量初始化

執(zhí)行父類的構(gòu)造函數(shù)

執(zhí)行子類的實(shí)例變量初始化

執(zhí)行子類的構(gòu)造函數(shù)

同時(shí),加載類的過程是線程私有的,別的線程無法進(jìn)入。

如果類已經(jīng)被加載:

靜態(tài)代碼塊和靜態(tài)變量不在重復(fù)執(zhí)行,再創(chuàng)建類對象時(shí),只執(zhí)行與實(shí)例相關(guān)的變量初始化和構(gòu)造方法。

static關(guān)鍵字

一個(gè)類中如果有成員變量或者方法被static關(guān)鍵字修飾,那么該成員變量或方法將獨(dú)立于該類的任何對象。它不依賴類特定的實(shí)例,被類的所有實(shí)例共享,只要這個(gè)類被加載,該成員變量或方法就可以通過類名去進(jìn)行訪問,它的作用用一句話來描述就是,不用創(chuàng)建對象就可以調(diào)用方法或者變量,這簡直就是為單例模式的代碼實(shí)現(xiàn)量身打造的。

下面將列舉幾種單例模式的實(shí)現(xiàn)方式,其關(guān)鍵方法都是用static修飾的,并且,為了避免單例的類被頻繁創(chuàng)建對象,我們可以用private的構(gòu)造函數(shù)來確保單例類無法被外部實(shí)例化。

懶漢和餓漢

在程序編寫上,一般將單例模式分為兩種,分別是餓漢式和懶漢式,

餓漢式:在類加載時(shí)就完成了初始化,所以類加載比較慢,但獲取對象的速度快。

懶漢式:在類加載時(shí)不初始化,等到第一次被使用時(shí)才初始化。

代碼實(shí)現(xiàn)

1、餓漢式 (可用)

public class Singleton {

    private final static Singleton INSTANCE = new Singleton();
    
    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }

}

這是比較常見的寫法,在類加載的時(shí)候就完成了實(shí)例化,避免了多線程的同步問題。當(dāng)然缺點(diǎn)也是有的,因?yàn)轭惣虞d時(shí)就實(shí)例化了,沒有達(dá)到Lazy Loading (懶加載) 的效果,如果該實(shí)例沒被使用,內(nèi)存就浪費(fèi)了。

2、普通的懶漢式 (線程不安全,不可用)

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

}

這是懶漢式中最簡單的一種寫法,只有在方法第一次被訪問時(shí)才會實(shí)例化,達(dá)到了懶加載的效果。但是這種寫法有個(gè)致命的問題,就是多線程的安全問題。假設(shè)對象還沒被實(shí)例化,然后有兩個(gè)線程同時(shí)訪問,那么就可能出現(xiàn)多次實(shí)例化的結(jié)果,所以這種寫法不可采用。

3、同步方法的懶漢式 (可用)

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

}

這種寫法是對getInstance()加了鎖的處理,保證了同一時(shí)刻只能有一個(gè)線程訪問并獲得實(shí)例,但是缺點(diǎn)也很明顯,因?yàn)?/strong>synchronized是修飾整個(gè)方法,每個(gè)線程訪問都要進(jìn)行同步,而其實(shí)這個(gè)方法只執(zhí)行一次實(shí)例化代碼就夠了,每次都同步方法顯然效率低下,為了改進(jìn)這種寫法,就有了下面的雙重檢查懶漢式。

4、雙重檢查懶漢式 (可用,推薦)

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

}

這種寫法用了兩個(gè)if判斷,也就是Double-Check,并且同步的不是方法,而是代碼塊,效率較高,是對第三種寫法的改進(jìn)。為什么要做兩次判斷呢?這是為了線程安全考慮,還是那個(gè)場景,對象還沒實(shí)例化,兩個(gè)線程A和B同時(shí)訪問靜態(tài)方法并同時(shí)運(yùn)行到第一個(gè)if判斷語句,這時(shí)線程A先進(jìn)入同步代碼塊中實(shí)例化對象,結(jié)束之后線程B也進(jìn)入同步代碼塊,如果沒有第二個(gè)if判斷語句,那么線程B也同樣會執(zhí)行實(shí)例化對象的操作了。

5、靜態(tài)內(nèi)部類 (可用,推薦)

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }

}

這是很多開發(fā)者推薦的一種寫法,這種靜態(tài)內(nèi)部類方式在Singleton類被裝載時(shí)并不會立即實(shí)例化,而是在需要實(shí)例化時(shí),調(diào)用getInstance方法,才會裝載SingletonInstance類,從而完成對象的實(shí)例化。

同時(shí),因?yàn)轭惖撵o態(tài)屬性只會在第一次加載類的時(shí)候初始化,也就保證了SingletonInstance中的對象只會被實(shí)例化一次,并且這個(gè)過程也是線程安全的。

6、枚舉 (可用、推薦)

public enum Singleton {
    INSTANCE;
}

這種寫法在《Effective JAVA》中大為推崇,它可以解決兩個(gè)問題:

1)線程安全問題。因?yàn)镴ava虛擬機(jī)在加載枚舉類的時(shí)候會使用ClassLoader的方法,這個(gè)方法使用了同步代碼塊來保證線程安全。

2)避免反序列化破壞對象,因?yàn)槊杜e的反序列化并不通過反射實(shí)現(xiàn)。

好了,單例模式的幾種寫法就介紹到這了,最后簡單總結(jié)一下單例模式的優(yōu)缺點(diǎn)

單例模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

單例類只有一個(gè)實(shí)例,節(jié)省了內(nèi)存資源,對于一些需要頻繁創(chuàng)建銷毀的對象,使用單例模式可以提高系統(tǒng)性能;

單例模式可以在系統(tǒng)設(shè)置全局的訪問點(diǎn),優(yōu)化和共享數(shù)據(jù),例如前面說的Web應(yīng)用的頁面計(jì)數(shù)器就可以用單例模式實(shí)現(xiàn)計(jì)數(shù)值的保存。

缺點(diǎn)

單例模式一般沒有接口,擴(kuò)展的話除了修改代碼基本上沒有其他途徑。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/7190.html

相關(guān)文章

  • 我的Java設(shè)計(jì)-單例

    摘要:那有什么辦法保證只有一個(gè)領(lǐng)導(dǎo)人斯大林呢較常見的兩種方式餓漢式和懶漢式二實(shí)戰(zhàn)圖這里提示一點(diǎn),在學(xué)習(xí)設(shè)計(jì)模式的時(shí)候,圖會讓你更容易,而且深刻的去理解到該模式的核心。下一篇的設(shè)計(jì)模式是工廠方法模式。 ??就算不懂設(shè)計(jì)模式的兄弟姐妹們,想必也聽說過單例模式,并且在項(xiàng)目中也會用上。但是,真正理解和熟悉單例模式的人有幾個(gè)呢?接下來我們一起來學(xué)習(xí)設(shè)計(jì)模式中最簡單的模式之一——單例模式 一、為什么叫單...

    Jensen 評論0 收藏0
  • Java基礎(chǔ)學(xué)習(xí)——多線程之單例設(shè)計(jì)(轉(zhuǎn))

    摘要:總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。二餓漢式單例餓漢式單例類在類初始化時(shí),已經(jīng)自行實(shí)例化靜態(tài)工廠方法餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。 概念:  Java中單例模式是一種常見的設(shè)計(jì)模式,單例模式的寫法有好幾種,這里主要介紹兩種:懶漢式單例、餓漢式單例。  單例模式有以下特點(diǎn):  1、單例類只能有一個(gè)實(shí)例。 ...

    dendoink 評論0 收藏0
  • 單例的終極實(shí)現(xiàn)方案

    摘要:如此便可使得這一實(shí)現(xiàn)方式能夠同時(shí)具備線程安全延遲加載以及節(jié)省大量同步判斷資源等優(yōu)勢,可以說是單例模式的最佳實(shí)現(xiàn)了 單例模式(Singleton)是一種使用率非常高的設(shè)計(jì)模式,其主要目的在于保證某一類在運(yùn)行期間僅被創(chuàng)建一個(gè)實(shí)例,并為該實(shí)例提供了一個(gè)全局訪問方法,通常命名為getInstance()方法。單例模式的本質(zhì)簡言之即是: 控制實(shí)例數(shù)目 以Java為例,單例模式通??煞譃轲I漢式和懶...

    Freelander 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<