日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

SingletonPattern單例模式

 頭號碼甲 2021-07-14

單例模式

1.定義

確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例

餓漢式單例模式

public class Singleton {
    private static final Singleton singleton = new Singleton();

    // 構(gòu)造器私有化,限制產(chǎn)生多個對象
    private Singleton() {}

    // 對外提供靜態(tài)方法獲取實例對象
    public static Singleton getInstence() {
      return singleton;
    }
}

2.應(yīng)用

2.1優(yōu)點

  • 由于單例模式在內(nèi)存中只有一個實例,減小了內(nèi)存開支。特別在一個對象需要頻繁的創(chuàng)建銷毀時,創(chuàng)建銷毀時性能無法優(yōu)化,此時的優(yōu)勢非常明顯
  • 由于單例模式只生成一個實例,減少了系統(tǒng)的性能開銷。當一個對象需要產(chǎn)生較多的資源時,如讀取配置,產(chǎn)生其它以來對象,可以通過在應(yīng)用啟動時直接產(chǎn)生一個單例對象,然后永久駐留內(nèi)存的方式解決(JavaEE中采用單例模式時需要注意JVM的垃圾回收機制)
  • 單例模式可以避免對同一資源的多重占用,例如寫文件操作

2.2缺點

  • 單例模式一般沒有接口,擴展性差
  • 單例模式不利于測試。在并行開發(fā)環(huán)境中,若單例模式?jīng)]有完成,不能進行測試

2.3使用場景

  • 生成唯一序列號的環(huán)境
  • 在整個項目中需要一個共享訪問點或共享數(shù)據(jù)。如一個Web頁面上的計數(shù)器,使用單例模式保持計數(shù)器的值,并確保是線程安全的
  • 創(chuàng)建一個對象時需要消耗的資源過多,如訪問IO和數(shù)據(jù)庫等資源
  • 需要定義大量的靜態(tài)常量和靜態(tài)方法(如工具類)的環(huán)境

2.4注意事項

在該并發(fā)情況下,需要注意單例模式的線程同步問題。單例模式有幾種不同的實現(xiàn)方式,餓漢式單例模式不會產(chǎn)生多實例的情況,以下方式則需要考慮線程同步問題

懶漢式單例模式

public class Singleton {
    private static final Singleton singleton = null;

    // 構(gòu)造器私有化,限制產(chǎn)生多個對象
    private Singleton() {}

    // 對外提供靜態(tài)方法獲取實例對象
    public static Singleton getInstence() {
        if (singleton == null) {
          singleton = new Singleton();
        }
      
        return singleton;
    }
}

懶漢式單例模式在低并發(fā)情況下尚不會出現(xiàn)問題,若系統(tǒng)壓力增大,并發(fā)量增加時可能在內(nèi)存中存在多個實例。如一個線程A執(zhí)行到singleton = new Singleton();但還沒有獲得到對象,此時對象初始化未完成,第二個線程B執(zhí)行到if (singleton == null) {那么線程B判斷條件也為true,于是繼續(xù)執(zhí)行下去,則A和B各獲得一個對象。

解決單例模式線程不安全的方法,可以在getInstence方法前或方法內(nèi)加synchronized關(guān)鍵字來實現(xiàn),建議采用餓漢式單例模式。

3.擴展

有上限的多例模式:產(chǎn)生固定數(shù)量對象的模式

public class Singleton {
    // 定義最多能產(chǎn)生的實例數(shù)量
    private static int maxNumOfInstance = 2;

    // 定義一個列表容納所有實例
    private static List<Singleton> singletonList = new ArrayList<>();

    // 定義當前對象實例的序號
    private static int countNumOfInstance = 0;

    // 產(chǎn)生所有的對象
    static {
        for (int i = 0; i < maxNumOfInstance; i++) {
            singletonList.add(new Singleton())
        }
    }

    private Singleton() {}

    public static Singleton getInstence() {
      Random random = new Random();
      countNumOfInstance = random.nextInt(maxNumOfInstance);

      return singletonList.get(countNumOfInstance);
    }
}

考慮到線程安全問題可以使用Vector來代替。采用有上限的多例模式,可以在設(shè)計時決定內(nèi)存中有多少個實例,方便系統(tǒng)擴展,修正單例可能存在的性能問題,提高系統(tǒng)的響應(yīng)速度。如讀取文件,可以在系統(tǒng)啟動時完成初始化工作,在內(nèi)存中啟動固定數(shù)量的Reader實例。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多