成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

設(shè)計(jì)模式:?jiǎn)卫J?(關(guān)于餓漢式和懶漢式)

Darkgel / 1560人閱讀

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

定義

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

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

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

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

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

類(lèi)加載順序

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

如果類(lèi)還沒(méi)有被加載:

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

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

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

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

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

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

同時(shí),加載類(lèi)的過(guò)程是線程私有的,別的線程無(wú)法進(jìn)入。

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

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

static關(guān)鍵字

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

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

懶漢和餓漢

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

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

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

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

1、餓漢式 (可用)

public class Singleton {

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

    public static Singleton getInstance(){
        return INSTANCE;
    }

}

這是比較常見(jiàn)的寫(xiě)法,在類(lèi)加載的時(shí)候就完成了實(shí)例化,避免了多線程的同步問(wèn)題。當(dāng)然缺點(diǎn)也是有的,因?yàn)轭?lèi)加載時(shí)就實(shí)例化了,沒(méi)有達(dá)到Lazy Loading (懶加載) 的效果,如果該實(shí)例沒(méi)被使用,內(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;
    }

}

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

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

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

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

}

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

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;
    }

}

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

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

public class Singleton {

    private Singleton() {}

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

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

}

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

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

6、枚舉 (可用、推薦)

public enum Singleton {
    INSTANCE;
}

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

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

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

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

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

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

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

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

缺點(diǎn)

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/7190.html

相關(guān)文章

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

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

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

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

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

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

    Freelander 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<