設(shè)計(jì)模式系列-單例模式

1 單例模式

單例模式:確保某一個(gè)類只有一個(gè)實(shí)例,自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。

使用場(chǎng)景

確保某個(gè)類只有一個(gè)對(duì)象的場(chǎng)景,避免產(chǎn)生多個(gè)對(duì)象消耗資源,或者某個(gè)對(duì)象應(yīng)該有且只有一個(gè)的場(chǎng)景。

特點(diǎn)

1.構(gòu)造函數(shù)不對(duì)外開放,一般為private

2.通過(guò)靜態(tài)方法返回單例類的對(duì)象

3.確保對(duì)象只有一個(gè),尤其是在多線程的情況下

4.確保單例類對(duì)象在反序列化時(shí)不會(huì)重新創(chuàng)建對(duì)象

寫單例

一:餓漢模式

    public class Singleton {
        private static final Singleton singleton = new Singleton();
        private Singleton(){
        }
        public static Singleton getInstance(){
            return singleton;
        }
        //  do.....
    }

二:懶漢模式

    public class SingletonV2 {
        private static SingletonV2 singletonV2 = null;
        private SingletonV2(){
        }
        public static synchronized SingletonV2 getInstance(){
            if(singletonV2 != null){
                singletonV2 = new SingletonV2();
            }
            return singletonV2;
        }
        // do....
    }

優(yōu)點(diǎn):只有在使用時(shí)才會(huì)被實(shí)例化
缺點(diǎn):每次使用都要進(jìn)行同步,即使單例已經(jīng)存在,造成不必要的同步開銷

三:DCL實(shí)現(xiàn)單例(雙鎖)

    public class SingletonV3 {
        private static SingletonV3 singletonV3 = null;
        private SingletonV3(){
        }
        public static SingletonV3 getInstance(){
            if(singletonV3 == null){
                synchronized (SingletonV3.class){
                    if(singletonV3 == null){
                        singletonV3 = new SingletonV3();
                    }
                }
            }
            return singletonV3;
        }
        // do ....
    }

DCL失效問(wèn)題:

singletonV3 = new SingletonV3(); 一句代碼,卻不是原子性操作,會(huì)被編譯成多條匯編指令,但大致作了三件事:

1.給SingletonV3的實(shí)例分配內(nèi)存;

2.調(diào)用SingletonV3的構(gòu)造函數(shù),初始化字段;

3.將singletonV3指向分配的內(nèi)存空間(這時(shí)singletonV3 不為 null)

JDK1.5之前java編譯器允許處理器亂序執(zhí)行,上面2,3的執(zhí)行順序是無(wú)法保證的,所以執(zhí)行順序可能是1-2-3,也可能是1-3-2,如果是后者,則有可能出現(xiàn)3執(zhí)行完畢,2還未執(zhí)行,此時(shí)singletonV3已經(jīng)不為null,但另一個(gè)線程取走singletonV3,使用就會(huì)出錯(cuò)。

jdk1.5之后,使用volatile,修改為private volatile static SingletonV3 singletonV3 = null;就可以保證singletonV3保證每次都是從主內(nèi)存中讀取。

能夠在絕大多數(shù)情況保證單例對(duì)象的唯一性,除非在并發(fā)場(chǎng)景比較復(fù)雜或JDK低于6的版本下使用。

四:靜態(tài)內(nèi)部類實(shí)現(xiàn)

    public class SingletonV4 {
        private SingletonV4(){
        }
        public static SingletonV4 getInstance(){
            return SingletonHolder.singletonV4;
        }
        private static class SingletonHolder{
            private static final SingletonV4 singletonV4 = new SingletonV4();
        }
    }

第一次加載SingletonV4時(shí)并不會(huì)初始化singletonV4,只有第一次調(diào)用getInstance()才會(huì)導(dǎo)致加載SingletonHolder類,線程安全,而且保證對(duì)象的唯一性,切延遲實(shí)例化,推薦的單例實(shí)現(xiàn)方式。

五:枚舉實(shí)現(xiàn)單例

public enum SIngletonEnum {
    Instance;
    // do something
    private int num = 10;
    public int doSomething(){
        return num;
    }
    //
}

枚舉單例的最大特點(diǎn)就是簡(jiǎn)單,枚舉不僅能夠有字段,還能夠有方法,枚舉單例是線程安全的。

反序列化

序列化操作提供了一個(gè)很特別的鉤子(hook)-類中具有一個(gè)私有的被實(shí)例化的方法readresolve(),這個(gè)方法可以確保類的開發(fā)人員在序列化將會(huì)返回怎樣的object上具有發(fā)言權(quán)。

     private Object readResolve() throws ObjectStreamException {
         return getInstance();
     }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 單例模式的動(dòng)機(jī) 對(duì)于一個(gè)軟件系統(tǒng)的某些類而言,我們無(wú)須創(chuàng)建多個(gè)實(shí)例。舉個(gè)大家都熟知的例子——Windows任務(wù)...
    justCode_閱讀 1,558評(píng)論 2 9
  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單、最易理解的設(shè)計(jì)模式,也因?yàn)樗暮?jiǎn)潔易懂,是項(xiàng)目中最...
    成熱了閱讀 4,545評(píng)論 4 34
  • 單例模式介紹 單例模式是設(shè)計(jì)模式中最常見(jiàn)也最簡(jiǎn)單的一種設(shè)計(jì)模式,單例模式的主要作用是保證在Java程序中,某個(gè)類只...
    暮染1閱讀 306評(píng)論 0 0
  • 個(gè)人博客CoorChice,https://chenbingx.github.io/ ,最新文章將會(huì)首發(fā)Coor...
    CoorChice閱讀 2,147評(píng)論 2 18
  • 有很長(zhǎng)一段時(shí)間沒(méi)有靜下來(lái)寫點(diǎn)東西了,之前喜歡寫在QQ空間里,以至于這段時(shí)間很多朋友都會(huì)問(wèn)我:怎么不見(jiàn)你寫什...
    剪痕閱讀 293評(píng)論 2 3

友情鏈接更多精彩內(nèi)容