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

資訊專欄INFORMATION COLUMN

Java 設(shè)計(jì)模式之單例模式

everfight / 3441人閱讀

摘要:在設(shè)計(jì)模式一書中,將單例模式稱作單件模式。通過關(guān)鍵字,來保證不會(huì)同時(shí)有兩個(gè)線程進(jìn)入該方法的實(shí)例對(duì)象改善多線程問題為了符合大多數(shù)程序,很明顯地,我們需要確保單例模式能在多線程的情況下正常工作。

在《Head First 設(shè)計(jì)模式》一書中,將單例模式稱作單件模式。這里為了適應(yīng)大環(huán)境,把它稱之為大家更熟悉的單例模式。

一、了解單例模式

1.1 什么是單例模式

單例模式確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)安全訪問點(diǎn)。

我們把某個(gè)類設(shè)計(jì)成自己管理的一個(gè)多帶帶實(shí)例,同時(shí)也避免其他類再自行產(chǎn)生實(shí)例。想要獲取單例實(shí)例,通過單例類是唯一的途徑。單例類提供對(duì)這個(gè)實(shí)例的全局訪問點(diǎn):當(dāng)你需要實(shí)例時(shí),向類查詢,它會(huì)返回單個(gè)實(shí)例。

1.2 單例模式 UML 圖解

1.3 單例模式應(yīng)用場(chǎng)景

需要頻繁實(shí)例化然后銷毀的對(duì)象。

創(chuàng)建對(duì)象時(shí)耗時(shí)過多或者耗資源過多,但又經(jīng)常用到的對(duì)象。比如線程池、緩存、日志對(duì)象等。

有狀態(tài)的工具類對(duì)象。

頻繁訪問數(shù)據(jù)庫或文件的對(duì)象。

以及要求只有一個(gè)對(duì)象的場(chǎng)景。

二、單例模式具體應(yīng)用

2.1 經(jīng)典的單例模式實(shí)現(xiàn)

采用經(jīng)典單例模式實(shí)現(xiàn)代碼有一個(gè)特點(diǎn):如果我們不需要這個(gè)實(shí)例 (調(diào)用 getInstance() 方法),它就永遠(yuǎn)不會(huì)產(chǎn)生。因此這種方式也被稱為“延遲實(shí)例化”(lazy instantiaze)。也被大家稱為“懶漢式”。

單例類 Singleton

package com.jas.singleton;

public class Singleton {
    // 用靜態(tài)變量來記錄 Singleton 類的唯一實(shí)例
    private static Singleton uniqueInstance;

    /**
     * 把構(gòu)造器聲明為私有的,只有自己 Singleton 內(nèi)部才可以調(diào)用構(gòu)造器
     */
    private Singleton(){}

    /**
     * getInstance() 方法來實(shí)例化對(duì)象
     * 
     * @return Singleton 的實(shí)例對(duì)象
     */
    public static Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton();
        }
        
        return uniqueInstance;
    }
}

測(cè)試類

package com.jas.singleton;

public class SingletonTest {
    public static void main(String[] args) {
        
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        
        System.out.println(singleton1 == singleton2);
    }
}

     /**
     * 輸出
     * true
     */

這雖然是經(jīng)典的單例模式,但是這樣做卻存在著一個(gè)嚴(yán)重的問題:當(dāng)多個(gè)線程同時(shí)訪問 getInstance() 方法時(shí),會(huì)產(chǎn)生線程安全問題,可能導(dǎo)致產(chǎn)生的實(shí)例可能會(huì)有多個(gè),這樣就違反了單例的原則。

2.2 處理多線程

存在線程安全問題,我們的第一反應(yīng)可能是加同步鎖。就像下面這樣,這樣做是可以解決線程安全問題,但是卻降低了性能。因?yàn)橹挥性诘谝淮螆?zhí)行該方法的時(shí)候,才真正需要同步。之后再調(diào)用此方法,同步反而會(huì)成為一種累贅。

    /**
     * 通過 synchronized 關(guān)鍵字,來保證不會(huì)同時(shí)有兩個(gè)線程進(jìn)入該方法
     * 
     * @return Singleton 的實(shí)例對(duì)象
     */
    public synchronized static Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton();
        }
        
        return uniqueInstance;
    }

2.3 改善多線程問題

為了符合大多數(shù) Java 程序,很明顯地,我們需要確保單例模式能在多線程的情況下正常工作。但是同步的做法會(huì)擊垮其性能,所以提供以下幾種方法來解決問題。

(1) 直接同步

直接同步雖然會(huì)降低性能,但是如果你的程序可以承受 getInstance() 造成的額外代價(jià),同步確實(shí)是一種既簡單又有效的方法。但是你必須知道,同步一個(gè)方法,可能會(huì)使程序的執(zhí)行效率下降幾十倍。因此,如果你需要頻繁使用單例對(duì)象,那么你就要重新考慮設(shè)計(jì)了。

(2) “急切”創(chuàng)建實(shí)例

如果應(yīng)用程序總是創(chuàng)建并使用單例創(chuàng)建的對(duì)象,或者在創(chuàng)建和運(yùn)行時(shí)方面的負(fù)擔(dān)不太嚴(yán)重,你可以急切 (early) 創(chuàng)建此對(duì)象。這種方式也被大家稱為“惡漢式”。就像下面這樣

package com.jas.singleton;

public class Singleton {
    //在靜態(tài)初始化器中創(chuàng)建對(duì)象,用來保證線程安全
    private static Singleton uniqueInstance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return uniqueInstance;
    }
}

利用上面這種做法,我們依賴 JVM 在加載這個(gè)類時(shí)馬上創(chuàng)建此唯一的實(shí)例。JVM 保證在任何時(shí)候任何線程訪問 getInstance() 方法之前,一定會(huì)先創(chuàng)建此實(shí)例。這樣一來就可以解決多線程之間的安全問題。

(3)雙重檢驗(yàn)加鎖

利用雙重檢驗(yàn)加鎖 (double-checked locking),首先檢查實(shí)例是否已經(jīng)被創(chuàng)建了,如果未創(chuàng)建,“才”開始同步。這樣一來,只有第一次會(huì)同步,這樣做正是我們想要的。

package com.jas.singleton;

public class Singleton {
    //volatile 關(guān)鍵字用來保證內(nèi)存可見性,使多線程正確處理 uniqueInstance 對(duì)象
    private static volatile Singleton uniqueInstance;

    private Singleton(){}

    public static Singleton getInstance(){
        //使用這種方式,只有第一次才會(huì)徹底訪問并執(zhí)這里的代碼
        if(uniqueInstance == null){     //檢查實(shí)例,如果不存在進(jìn)入同步區(qū)
            synchronized (Singleton.class){
                if(uniqueInstance == null){     //進(jìn)入同步區(qū)后,再檢查一次。如果為 null,才開始創(chuàng)建實(shí)例
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

如果你性能是你關(guān)心的重點(diǎn),那么這種方式會(huì)幫你大大減少訪問 getInstance() 時(shí)的時(shí)間消耗。需要在注意的是:這種雙重檢驗(yàn)加鎖的方式并不適用于 1.4 及之前更早的版本。

三、單例模式總結(jié)

3.1 優(yōu)缺點(diǎn)總結(jié)

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

實(shí)例控制:單例模式會(huì)阻止其他對(duì)象實(shí)例化其自己的單例對(duì)象的副本,從而確保所有對(duì)象都訪問唯一實(shí)例。

靈活性:因?yàn)轭惪刂屏藢?shí)例化過程,所以類可以靈活更改實(shí)例化過程。

缺點(diǎn)

開銷:雖然數(shù)量很少,但如果每次對(duì)象請(qǐng)求引用時(shí)都要檢查是否存在類的實(shí)例。

可能的開發(fā)混淆:使用單例對(duì)象(尤其在類庫中定義的對(duì)象)時(shí),開發(fā)人員必須記住自己不能使用 new 關(guān)鍵字實(shí)例化對(duì)象。因?yàn)榭赡軣o法訪問庫源代碼,因此應(yīng)用程序開發(fā)人員可能會(huì)意外發(fā)現(xiàn)自己無法直接實(shí)例化此類。

對(duì)象生存期:不能解決刪除單個(gè)對(duì)象的問題。在提供內(nèi)存管理的語言,只有單例類能夠?qū)е聦?shí)例被取消分配,因?yàn)樗瑢?duì)該實(shí)例的私有引用。

3.2 部分知識(shí)總結(jié)

單例模式確保程序中一個(gè)類最多只有一個(gè)實(shí)例。單例模式也提供訪問這個(gè)實(shí)例的全局點(diǎn)。

如果你使用多個(gè)類加載器,可能導(dǎo)致單例模式失效,從而產(chǎn)生多個(gè)實(shí)例。

確定性能和資源上的限制,我們應(yīng)當(dāng)選擇合適的方案來實(shí)現(xiàn)單例模式。

參考資料

《Head First 設(shè)計(jì)模式》

https://www.cnblogs.com/tufujie/p/5614682.html

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

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

相關(guān)文章

  • 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)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。 概念:  Java中單例模式是一種常見的設(shè)計(jì)模式,單例模式的寫法有好幾種,這里主要介紹兩種:懶漢式單例、餓漢式單例。  單例模式有以下特點(diǎn):  1、單例類只能有一個(gè)實(shí)例。 ...

    dendoink 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式單例模式

    摘要:原文博客地址單例模式系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。中的單例模式利用閉包實(shí)現(xiàn)了私有變量兩者是否相等弱類型,沒有私有方法,使用者還是可以直接一個(gè),也會(huì)有方法分割線不是單例最簡單的單例模式,就是對(duì)象。 原文博客地址:https://finget.github.io/2018/11/06/single/ 單例模式 系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。實(shí)現(xiàn)方法一般是先判斷實(shí)例是否存在,...

    lk20150415 評(píng)論0 收藏0
  • 優(yōu)才公開課筆記:php設(shè)計(jì)模式(一) 單例模式

    摘要:最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。不過因?yàn)椴恢С侄嗑€程所以不需要考慮這個(gè)問題了。 最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在PHP中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。 一、設(shè)計(jì)模式簡介 首先我們來認(rèn)識(shí)一下什么是設(shè)計(jì)模式: 設(shè)計(jì)模式是一套被反復(fù)使用、容易被他人理解的、可靠的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。 設(shè)計(jì)模式不...

    guyan0319 評(píng)論0 收藏0
  • Java 23種設(shè)計(jì)模式 單例模式 7種實(shí)現(xiàn)方式

    摘要:一懶漢式線程不安全懶漢式線程不安全私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建創(chuàng)建實(shí)例二懶漢式線程安全懶漢式線程安全私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建創(chuàng)建實(shí)例線程安全三餓漢式線程安全餓漢式私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建靜態(tài)初始化由保證 一、懶漢式(線程不安全) package com.java.singleton; //懶漢式 線程不安全 public class LazySi...

    IntMain 評(píng)論0 收藏0
  • 設(shè)計(jì)模式系列單例模式

    摘要:下面我們來看看看中的單例模式,中使用的是單例注冊(cè)表的特殊方式實(shí)現(xiàn)的單例模式,所以說模式是死的,需要靈活得運(yùn)用。 本文循序漸進(jìn)介紹單例模式的幾種實(shí)現(xiàn)方式,以及Jdk中使用到單例模式的例子,以及sring框架中使用到的單例模式例子。 餓漢式 package signgleton; /** * 單例模式簡單的實(shí)現(xiàn) */ public class Singleton { priv...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<