日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单例模式-序列号生成器

發(fā)布時間:2023/12/31 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单例模式-序列号生成器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 序列號生成器

設計一個全局的序列號生成器,返回long類型,要求生成的序列號全局唯一且遞增。

序列號的實現(xiàn)很簡單,如下:

class SerialGenerator{private long code;// 返回下一個號碼public synchronized long next(){return ++code;} }

如果不是單例,多個生成器實例生成的序列號都是從0開始,會造成沖突,優(yōu)化如下:

class SerialGenerator{private long code;private static final SerialGenerator INSTANCE = new SerialGenerator();// 私有化構(gòu)造器,防止外部newprivate SerialGenerator(){}public synchronized long next(){return ++code;}public static SerialGenerator getInstance(){return INSTANCE;} }

客戶端調(diào)用:

public class Client {public static void main(String[] args) {SerialGenerator serialGenerator = SerialGenerator.getInstance();serialGenerator.next();} }

這就是單例模式。

2. 單例模式的定義

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

單例模式屬于創(chuàng)建型模式,它的核心操作是:

  • 私有化構(gòu)造器,防止其他類通過new關鍵字創(chuàng)建實例。
  • 類內(nèi)部自行實例化,并用靜態(tài)常量保存(也可延遲實例化)。
  • 提供一個公開的靜態(tài)方法來訪問這個實例。
  • 也可以將靜態(tài)常量聲明為public,外部類直接訪問單例,但是不建議這么做,調(diào)用getInstance()方法來獲取實例,方便以后擴展。

    單例模式通用類圖

    3. 單例模式的擴展

    上面寫的例子屬于【餓漢式】,不管客戶端是否需要訪問實例,只要Class文件被Load到內(nèi)存,實例就會被創(chuàng)建。

    3.1 DCL懶漢式

    DCL全稱是:Double Check Lock,雙重檢查加鎖,是【懶漢式】的一種實現(xiàn)方式。實例默認不會創(chuàng)建,只有當客戶端真正需要訪問實例時,實例才會被創(chuàng)建,重點是控制并發(fā)訪問。

    public class SerialGenerator_DCL {private long code;private static volatile SerialGenerator_DCL instance;public synchronized long next() {return ++code;}public static SerialGenerator_DCL getInstance() {if (instance == null) {synchronized (SerialGenerator_DCL.class) {if (instance == null) {// recheckinstance = new SerialGenerator_DCL();}}}return instance;} }

    3.2 內(nèi)部類實現(xiàn)單例

    【懶漢式】的另外一種實現(xiàn)方式,通過內(nèi)部類來持有實例對象,當單例類被Load時,內(nèi)部類并不會被加載,也就不會創(chuàng)建實例,只有當客戶端真正需要訪問實例時,內(nèi)部類才會被加載并創(chuàng)建實例。

    public class SerialGenerator_InnerClass {private long code;private SerialGenerator_InnerClass() {}public synchronized long next() {return ++code;}private static class InnerClass {final static SerialGenerator_InnerClass INSTANCE = new SerialGenerator_InnerClass();}public static SerialGenerator_InnerClass getInstance() {return InnerClass.INSTANCE;} }

    3.3 單例枚舉

    《Effective Java》的作者Joshua Bloch在《用私有構(gòu)造器或者枚舉類型強化Singleton屬性》一節(jié)中提出了實現(xiàn)單例的另一種方式:包含單個元素的枚舉類型。

    前面寫的幾種單例實現(xiàn)方式,從嚴格意義上來說,是有“缺陷”的。通過Java的反射技術,可以調(diào)用私有構(gòu)造器創(chuàng)建多個實例,另外,反序列化也會對單例造成破壞,具體可以查看筆者的博客:《你寫的單例真的安全嗎?》。

    枚舉的方式可以避免這種破壞,是實現(xiàn)單例的最佳方式:

    public enum SerialGenerator_Enum {INSTANCE;private long code;public synchronized long next() {return ++code;} }

    4. 單例模式的優(yōu)缺點

    優(yōu)點

  • 減少了內(nèi)存的開支,因為單例模式在內(nèi)存中只有一個實例。
  • 減少了系統(tǒng)的性能開銷,如果一個對象需要被頻繁的創(chuàng)建和銷毀,使用單例永久駐留在內(nèi)存會很有優(yōu)勢。
  • 避免對資源的多重占用,例如寫文件。
  • 缺點

  • 擴展困難,單例模式一般沒有接口,因為它要求類“自行實例化”。若要擴展,只能修改代碼。
  • 與單一職責沖突,單例類既要負責業(yè)務邏輯,又要保證是單例。
  • 5. 總結(jié)

    單例模式算是23種設計模式中最簡單的一個了,它要求類自行實例化,并向全局提供這個實例。單例模式應用非常的廣泛,例如Spring的IOC容器中,每個Bean默認就是單例的,JDK的java.lang.Runtime就是用【餓漢式】實現(xiàn)的單例。

    總結(jié)

    以上是生活随笔為你收集整理的单例模式-序列号生成器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。