設(shè)計(jì)模式(一)--深入單例模式(涉及線程安全問(wèn)題)

這又是一個(gè)新的系列啦忙迁,探究各大設(shè)計(jì)模式在開(kāi)發(fā)中必須注意思考的一些問(wèn)題,以及它們的多向使用。

文章結(jié)構(gòu):(1)單例模式概念以及優(yōu)缺點(diǎn)(2)各式各樣的單例及其線程安全問(wèn)題溃蔫。(3)使用推薦。


單例模式概念以及優(yōu)缺點(diǎn):

(1)定義:

要求一個(gè)類只能生成一個(gè)對(duì)象琳猫,所有對(duì)象對(duì)它的依賴相同伟叛。

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

1. 只有一個(gè)實(shí)例,減少內(nèi)存開(kāi)支脐嫂。應(yīng)用在一個(gè)經(jīng)常被訪問(wèn)的對(duì)象上

2. 減少系統(tǒng)的性能開(kāi)銷痪伦,應(yīng)用啟動(dòng)時(shí),直接產(chǎn)生一單例對(duì)象雹锣,用永久駐留內(nèi)存的方式网沾。

3.避免對(duì)資源的多重占用

4.可在系統(tǒng)設(shè)置全局的訪問(wèn)點(diǎn),優(yōu)化和共享資源訪問(wèn)蕊爵。

(3)缺點(diǎn):

1.一般沒(méi)有接口辉哥,擴(kuò)展困難。原因:接口對(duì)單例模式?jīng)]有任何意義攒射;要求“自行實(shí)例化”醋旦,并提供單一實(shí)例,接口或抽象類不可能被實(shí)例化会放。(當(dāng)然饲齐,單例模式可以實(shí)現(xiàn)接口、被繼承咧最,但需要根據(jù)系統(tǒng)開(kāi)發(fā)環(huán)境判斷)

2.單例模式對(duì)測(cè)試是不利的捂人。如果單例模式?jīng)]完成,是不能進(jìn)行測(cè)試的矢沿。

3.單例模式與單一職責(zé)原則有沖突滥搭。原因:一個(gè)類應(yīng)該只實(shí)現(xiàn)一個(gè)邏輯,而不關(guān)心它是否是單例捣鲸,是不是要單例取決于環(huán)境瑟匆;單例模式把“要單例”和業(yè)務(wù)邏輯融合在一個(gè)類。

(4)使用場(chǎng)景:

1.要求生成唯一序列化的環(huán)境

2.項(xiàng)目需要的一個(gè)共享訪問(wèn)點(diǎn)或共享的數(shù)據(jù)點(diǎn)

3.創(chuàng)建一個(gè)對(duì)象需要消耗資源過(guò)多的情況栽惶。如:要訪問(wèn)IO和 數(shù)據(jù)庫(kù)等資源愁溜。

4.需要定義大量的靜態(tài)常量和靜態(tài)方法(如工具類)的環(huán)境⊥獬В可以采用單例模式或者直接聲明static的方式冕象。

(5)注意事項(xiàng):

1.類中其他方法,盡量是static

2.注意JVM的垃圾回收機(jī)制酣衷。

如果一個(gè)單例對(duì)象在內(nèi)存長(zhǎng)久不使用交惯,JVM就認(rèn)為對(duì)象是一個(gè)垃圾次泽。所以如果針對(duì)一些狀態(tài)值穿仪,如果回收的話席爽,應(yīng)用就會(huì)出現(xiàn)故障。

3.采用單例模式來(lái)記錄狀態(tài)值的類的兩大方法:

(一)啊片、由容器管理單例的生命周期只锻。Java EE容器或者框架級(jí)容器,自行管理對(duì)象的生命周期紫谷。
(二)狀態(tài)隨時(shí)記錄齐饮。異步記錄的方式或者使用觀察者模式,記錄狀態(tài)變化笤昨,確保重新初始化也可從資源環(huán)境獲得銷毀前的數(shù)據(jù)祖驱。

二、各式各樣的單例及其線程安全問(wèn)題:

(1)懶漢式單例:

意思:就是需要使用這個(gè)對(duì)象的時(shí)候才去創(chuàng)建這個(gè)對(duì)象瞒窒。

//懶漢式單例
public class Singleton1 {
    private static Singleton1 singleton1=null;
    public Singleton1(){

    }
    public static Singleton1 getInstance(){
        if (singleton1==null){
            try {
                Thread.sleep(200);//我們知道初始化一個(gè)對(duì)象需要一定時(shí)間的嘛捺僻,我們用sleep假設(shè)這個(gè)時(shí)間
                singleton1 = new Singleton1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return singleton1;
    }
}
//測(cè)試線程
public class SingleThread1 extends Thread {
//哈希值對(duì)應(yīng)的是唯一的嘛,如果不一樣了崇裁,就說(shuō)明使用的不是同一個(gè)對(duì)象咯匕坯。
    @Override
    public void run() {
        System.out.println(Singleton1.getInstance().hashCode());
    }

}

//測(cè)試類
public class SingletonTest {

    public static void main(String []args){
        SingleThread1[] thread1s = new SingleThread1[10];
        for (int i= 0;i<thread1s.length;i++){
            thread1s[i] = new SingleThread1();
        }
        for (int j = 0; j < thread1s.length; j++) {
            thread1s[j].start();
        }
    }
}
//打印的結(jié)果:
569219718
1259146238
565373737
732830316
679555294
1886445805
1557403724
635681435
622018771
1439317371

線程安全的懶漢式單例設(shè)計(jì):

1.鎖住獲取方法方式:

public class Singleton3 {
    private static Singleton3 instance = null;

    private Singleton3(){}
    //鎖住獲取方法的方式
    public synchronized static Singleton3 getInstance() {
        try {
            if(instance != null){
            }else{
                Thread.sleep(300);
                instance = new Singleton3();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }
}

2.鎖住部分代碼塊的方式:

public class Singleton2 {
    private static Singleton2 instance = null;
     private Singleton2(){
     }
    public static Singleton2 getInstance() {
        try {
            //鎖住代碼塊的方式
            synchronized (Singleton2.class) {
                if(instance != null){

                }else{
                    Thread.sleep(200);
                    instance = new Singleton2();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }
}

3.鎖住初始化對(duì)象操作的方式:但是!0挝取葛峻!這不是線程安全的!巴比!一會(huì)有這個(gè)方式的優(yōu)化從而實(shí)現(xiàn)線程安全术奖。

為什么?轻绞?

因?yàn)槎鄠€(gè)訪問(wèn)已經(jīng)進(jìn)入到創(chuàng)建的那里了腰耙。

public class Singleton4 {
    private static Singleton4 instance = null;
    private Singleton4(){}
    public static Singleton4 getInstance() {
        try {
            if(instance != null){
            }else{
                Thread.sleep(300);
                //只鎖住初始化操作的方式
                synchronized (Singleton4.class) {
                    instance = new Singleton4();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }
}

4.鎖住初始化對(duì)象操作的方式,但有個(gè)再檢查操作:

public class Singleton5 {
    //使用volatile關(guān)鍵字保其可見(jiàn)性
    volatile private static Singleton5 instance = null;
    private Singleton5(){}
    public static Singleton5 getInstance() {
        try {
            if(instance != null){
            }else{
                Thread.sleep(300);
                //鎖住初始化操作的方式
                synchronized (Singleton5.class) {
                    if(instance == null){//二次檢查
                        instance = new Singleton5();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }
}

使用了volatile關(guān)鍵字來(lái)保證其線程間的可見(jiàn)性铲球;在同步代碼塊中使用二次檢查挺庞,以保證其不被重復(fù)實(shí)例化。集合其二者稼病,這種實(shí)現(xiàn)方式既保證了其高效性选侨,也保證了其線程安全性。

解析volatile在此的作用:

volatile(涉及java內(nèi)存模型的知識(shí))會(huì)禁止CPU對(duì)內(nèi)存訪問(wèn)重排序(并不一定禁止指令重排)然走,也就是CPU執(zhí)行初始化操作援制,那么他會(huì)保證其他CPU看到的操作順序是1.給 instance 分配內(nèi)存--2.調(diào)用 Singleton 的構(gòu)造函數(shù)來(lái)初始化成員變量--3.將instance對(duì)象指向分配的內(nèi)存空間(執(zhí)行完這步 instance 就為非 null 了),(雖然在CPU內(nèi)由于流水線多發(fā)射并不一定是這個(gè)順序)

不使用volatile的問(wèn)題是什么呢芍瑞?晨仑?

在 JVM 的即時(shí)編譯器中存在指令重排序的優(yōu)化。也就是說(shuō)上面的第二步和第三步的順序是不能保證的,最終的執(zhí)行順序可能是 1-2-3 也可能是 1-3-2洪己。如果是后者妥凳,則在 3 執(zhí)行完畢、2 未執(zhí)行之前答捕,被線程二搶占了逝钥,這時(shí) instance 已經(jīng)是非 null 了(但卻沒(méi)有初始化),所以線程二會(huì)直接返回 instance拱镐,然后使用艘款,然后順理成章地報(bào)錯(cuò)。

用volatile的意義并不在于其他線程一定要去內(nèi)存總讀取instance沃琅,而在于它限制了CPU對(duì)內(nèi)存操作的重拍序哗咆,使其他線程在看到3之前2一定是執(zhí)行過(guò)的。


(2)餓漢式單例:

意思是:類裝載時(shí)就實(shí)例化該單例類

public class Singleton6 {
    //一初始化類就初始化這個(gè)單例了R婷肌T兰稀!
    private static Singleton6 singleton6= new Singleton6();
    private Singleton6(){

    }
    public static Singleton6 getInstance(){
        return singleton6;
    }
}

基于classloder機(jī)制避免了多線程的同步問(wèn)題呜叫,不過(guò)空繁,instance在類裝載時(shí)就實(shí)例化,雖然導(dǎo)致類裝載的原因有很多種朱庆,在單例模式中大多數(shù)都是調(diào)用getInstance方法盛泡, 但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導(dǎo)致類裝載,這時(shí)候初始化instance顯然沒(méi)有達(dá)到lazy loading的效果娱颊。這個(gè)是沒(méi)有懶加載的功能的0了小!箱硕!

餓漢式單例變種:

public class Singleton7 {
    private static Singleton7 instance = null;
    static {
        instance = new Singleton7();
    }
    private Singleton7() {
    }
    public static Singleton7 getInstance() {
        return instance;
    }
}

(3)靜態(tài)內(nèi)部類實(shí)現(xiàn)懶加載:

//靜態(tài)內(nèi)部類單例
public class Singleton8 {
    private static class SingletonHolder {
        private static final Singleton8 INSTANCE = new Singleton8();
    }
    private Singleton8 (){}
    public static final Singleton8 getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

同樣利用了classloder的機(jī)制來(lái)保證初始化instance時(shí)只有一個(gè)線程拴竹,它跟餓漢式的兩種方式不同的是:餓漢式的兩種方式是只要Singleton類被裝載了,那么instance就會(huì)被實(shí)例化(沒(méi)有達(dá)到lazy loading效果)剧罩,而這種方式是Singleton類被裝載了栓拜,instance還未被初始化。因?yàn)镾ingletonHolder類沒(méi)有被主動(dòng)使用惠昔,只有顯示通過(guò)調(diào)用getInstance方法時(shí)幕与,才會(huì)顯示裝載SingletonHolder類,從而實(shí)例化instance镇防。想象一下啦鸣,如果實(shí)例化instance很消耗資源,我想讓他延遲加載来氧,另外一方面诫给,我不希望在Singleton類加載時(shí)就實(shí)例化香拉,因?yàn)槲也荒艽_保Singleton類還可能在其他的地方被主動(dòng)使用從而被加載,那么這個(gè)時(shí)候?qū)嵗痠nstance顯然是不合適的中狂。

靜態(tài)內(nèi)部類方式單例再度研究:序列化和反序列化問(wèn)題:

public class MySingleton implements Serializable {

    private static final long serialVersionUID = 1L;

    //內(nèi)部類
    private static class MySingletonHandler{
        private static MySingleton instance = new MySingleton();
    }

    private MySingleton(){}

    public static MySingleton getInstance() {
        return MySingletonHandler.instance;
    }
}
public class SaveAndReadForSingleton {
    public static void main(String[] args) {
        MySingleton singleton = MySingleton.getInstance();
        //創(chuàng)建個(gè)文件流
        File file = new File("MySingleton.txt");
        //使用節(jié)點(diǎn)流凫碌,直接與文件關(guān)聯(lián)
        try {
            //寫(xiě)入文件
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(singleton);
            fos.close();
            oos.close();
            System.out.println(singleton.hashCode());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            //讀取文件流
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            MySingleton rSingleton = (MySingleton) ois.readObject();
            fis.close();
            ois.close();
            System.out.println(rSingleton.hashCode());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

這樣的單例測(cè)試出來(lái)時(shí),hash是不一樣的吃型,因?yàn)闆](méi)有同步到序列化與反序列化問(wèn)題证鸥。說(shuō)明反序列化后返回的對(duì)象是重新實(shí)例化的僚楞,單例被破壞了勤晚。

解決:當(dāng)JVM從內(nèi)存中反序列化地"組裝"一個(gè)新對(duì)象時(shí),就會(huì)自動(dòng)調(diào)用readResolve方法來(lái)返回我們指定好的對(duì)象,readResolve允許class在反序列化返回對(duì)象前替換泉褐、解析在流中讀出來(lái)的對(duì)象赐写。實(shí)現(xiàn)readResolve方法,一個(gè)class可以直接控制反序化返回的類型和對(duì)象引用膜赃。

public class MySingleton1 implements Serializable {

    private static final long serialVersionUID = 1L;

    //內(nèi)部類
    private static class MySingletonHandler{
        private static MySingleton1 instance = new MySingleton1();
    }

    private MySingleton1(){}

    public static MySingleton1 getInstance() {
        return MySingletonHandler.instance;
    }

    //該方法在反序列化時(shí)會(huì)被調(diào)用挺邀,該方法不是接口定義的方法,有點(diǎn)兒約定俗成的感覺(jué)
    protected Object readResolve() throws ObjectStreamException {
        System.out.println("調(diào)用了readResolve方法跳座!");
        return MySingletonHandler.instance;
    }
}

修改SaveAndReadForSingleton文件中的MySingleton端铛,輸出

2133927002
調(diào)用了readResolve方法!解決序列化與反序列化問(wèn)題疲眷!
2133927002

(4)枚舉:

//枚舉實(shí)現(xiàn)單例
public enum EnumSingletonFactory {
    singletonFactory;
    private EnumSingleton instance;
    private EnumSingletonFactory(){//枚舉類的構(gòu)造方法在類加載是被實(shí)例化
        instance = new EnumSingleton();
    }
    public EnumSingleton getInstance(){
        return instance;
    }
}

在thread中調(diào)用實(shí)現(xiàn):

@Override  
    public void run() {     System.out.println(EnumFactory.singletonFactory.getInstance().hashCode());  
    }

但是此博客 引起我思考禾蚕,是違反單一職責(zé)的,因?yàn)樗┞读嗣杜e的細(xì)節(jié)狂丝,所以我們需要改造他换淆。

//使用工廠來(lái)生成枚舉類
//通過(guò)工廠類的靜態(tài)方法去訪問(wèn)枚舉類,然后通過(guò)枚舉類訪問(wèn)它的單例几颜。
public class ClassFactory {
    private enum MyEnumSingleton{
        singletonFactory;

        private EnumSingleton instance;

        private MyEnumSingleton(){//枚舉類的構(gòu)造方法在類加載是被實(shí)例化
            instance = new EnumSingleton();
        }

        public EnumSingleton getInstance(){
            return instance;
        }
    }

    public static EnumSingleton getInstance(){
        return MyEnumSingleton.singletonFactory.getInstance();
    }
}

在thread中調(diào)用實(shí)現(xiàn):

 @Override  
    public void run() {   
        System.out.println(ClassFactory.getInstance().hashCode());  
    }  

枚舉類的方式不僅能避免多線程同步問(wèn)題倍试,而且還能防止反序列化重新創(chuàng)建新的對(duì)象。不過(guò)實(shí)際工程代碼中蛋哭,很少去用此方式县习。


三、推薦使用:

上述的各種單例都講完了:基本是五種寫(xiě)法谆趾。懶漢准颓,惡漢,雙重校驗(yàn)鎖棺妓,枚舉和靜態(tài)內(nèi)部類攘已。

(1)餓漢式單例。

原因:類的加載機(jī)制保證了怜跑,類初始化時(shí)样勃,只執(zhí)行一次靜態(tài)代碼塊以及類變量初始化吠勘。直接保證了唯一性,保證了線程安全峡眶。(一般使用非靜態(tài)代碼塊方式)

(2)靜態(tài)內(nèi)部類方式:

原因:懶加載唄>绶馈!辫樱!應(yīng)用在一些十分巨大的單例bean中峭拘。


參考博客:此博客讓我對(duì)單例加深了一大層,感謝感謝Jㄊ睢鸡挠!

http://blog.csdn.net/cselmu9/article/details/51366946


好了,設(shè)計(jì)模式(一)--深入單例模式(涉及線程安全問(wèn)題)講完了搬男。本博客是我復(fù)習(xí)階段的一些筆記拣展,拿來(lái)分享經(jīng)驗(yàn)給大家。歡迎在下面指出錯(cuò)誤缔逛,共同學(xué)習(xí)1赴!!你的點(diǎn)贊是對(duì)我最好的支持:峙按脚!

更多內(nèi)容,可以訪問(wèn)JackFrost的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末敦冬,一起剝皮案震驚了整個(gè)濱河市辅搬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匪补,老刑警劉巖伞辛,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異夯缺,居然都是意外死亡蚤氏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)踊兜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)竿滨,“玉大人,你說(shuō)我怎么就攤上這事捏境∮谟危” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵垫言,是天一觀的道長(zhǎng)贰剥。 經(jīng)常有香客問(wèn)我,道長(zhǎng)筷频,這世上最難降的妖魔是什么蚌成? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任前痘,我火速辦了婚禮,結(jié)果婚禮上担忧,老公的妹妹穿的比我還像新娘芹缔。我一直安慰自己,他們只是感情好瓶盛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布最欠。 她就那樣靜靜地躺著,像睡著了一般惩猫。 火紅的嫁衣襯著肌膚如雪芝硬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天帆锋,我揣著相機(jī)與錄音吵取,去河邊找鬼禽额。 笑死锯厢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脯倒。 我是一名探鬼主播实辑,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼藻丢!你這毒婦竟也來(lái)了剪撬?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悠反,失蹤者是張志新(化名)和其女友劉穎残黑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體斋否,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梨水,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茵臭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疫诽。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旦委,靈堂內(nèi)的尸體忽然破棺而出奇徒,到底是詐尸還是另有隱情,我是刑警寧澤缨硝,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布摩钙,位于F島的核電站,受9級(jí)特大地震影響查辩,放射性物質(zhì)發(fā)生泄漏胖笛。R本人自食惡果不足惜奕短,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匀钧。 院中可真熱鬧翎碑,春花似錦、人聲如沸之斯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)佑刷。三九已至莉擒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瘫絮,已是汗流浹背涨冀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留麦萤,地道東北人鹿鳖。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像壮莹,于是被迫代替她去往敵國(guó)和親翅帜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單命满、最易理解的設(shè)計(jì)模式涝滴,也因?yàn)樗暮?jiǎn)潔易懂,是項(xiàng)目中最...
    成熱了閱讀 4,231評(píng)論 4 34
  • 前言 本文主要參考 那些年胶台,我們一起寫(xiě)過(guò)的“單例模式”歼疮。 何為單例模式? 顧名思義诈唬,單例模式就是保證一個(gè)類僅有一個(gè)...
    tandeneck閱讀 2,488評(píng)論 1 8
  • 1 單例模式的動(dòng)機(jī) 對(duì)于一個(gè)軟件系統(tǒng)的某些類而言韩脏,我們無(wú)須創(chuàng)建多個(gè)實(shí)例。舉個(gè)大家都熟知的例子——Windows任務(wù)...
    justCode_閱讀 1,432評(píng)論 2 9
  • 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用讯榕,讀取配置文件的內(nèi)容骤素。 很多應(yīng)用項(xiàng)目,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,676評(píng)論 12 68
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理愚屁,服務(wù)發(fā)現(xiàn)济竹,斷路器,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139