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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 进阶——单例模式

發布時間:2023/12/9 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 进阶——单例模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、單例模式概念及特點

? ? ? ??Java中單例模式是一種常見的設計模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。

  單例模式有一下特點:

? ? ? ? 1、單例類只能有一個實例。

  2、單例類必須自己自己創建自己的唯一實例。

? ? ? ? 3、單例類必須給所有其他對象提供這一實例。

而這個特點正是我們構造單例模式的方法:

1)構造函數私有化;

2)創建一個自身的對象;

3)向外提供方法。


  單例模式確保某個類只有一個實例,而且自行實例化并向整個系統提供這個實例。在計算機系統中,線程池、緩存、日志對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每臺計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

  正是由于這個特 點,單例對象通常作為程序中的存放配置信息的載體,因為它能保證其他對象讀到一致的信息。例如在某個服務器程序中,該服務器的配置信息可能存放在數據庫或 文件中,這些配置數據由某個單例對象統一讀取,服務進程中的其他對象如果要獲取這些配置信息,只需訪問該單例對象即可。這種方式極大地簡化了在復雜環境 下,尤其是多線程環境下的配置管理,但是隨著應用場景的不同,也可能帶來一些同步問題。


二、單例模式的舉例

1、餓漢方式的單例模式

[java]?view plaincopy
  • public?class?Singleton1?{??
  • /*構造函數私有化*/??
  • private?Singleton1(){??
  • }??
  • /*創建一個自身的對象*/??
  • private?static?final?Singleton1?instance?=?new?Singleton1();??
  • /*向外提供方法*/??
  • public?static?Singleton1?getInstance(){??
  • ????????return?instance;??
  • }??
  • }??
  • 特點:線程安全 但效率比較低 ?一開始就要加載類new一個對象


    2、懶漢方式的單例模式

    [java]?view plaincopy
  • //懶漢式單例類.在第一次調用的時候實例化???
  • ?public?class?Singleton2?{??
  • ?????//私有的默認構造子??
  • ?????private?Singleton2()?{}??
  • ?????//注意,這里沒有final??????
  • ?????private?static?Singleton2?single=null;??
  • ?????//靜態工廠方法???
  • ?????public?synchronized??static?Singleton2?getInstance()?{??
  • ??????????if?(single?==?null)?{????
  • ??????????????single?=?new?Singleton2();??
  • ??????????}????
  • ?????????return?single;??
  • ?????}??
  • ?}??
  • 特點:Singleton通過將構造方法限定為private避免了類在外部被實例化,在同一個虛擬機范圍內,Singleton的唯一實例只能通過getInstance()方法訪問。
    ? ? ? ? ? ?事實上,通過Java反射機制是能夠實例化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。

    ? ? ?但是以上懶漢式單例的實現沒有考慮線程安全問題,它是線程不安全的,并發環境下很可能出現多個Singleton實例,要實現線程安全,有以下三種方式,都是對getInstance這個方法改造,保證了懶漢式單例的線程安全,如果你第一次接觸單例模式,對線程安全不是很了解,可以先跳過下面這三小條,去看餓漢式單例,等看完后面再回頭考慮線程安全的問題:


    3、登記式單例類

    [java]?view plaincopy
  • //登記式單例類.??
  • ?//類似Spring里面的方法,將類名注冊,下次從里面直接獲取。??
  • ?public?class?Singleton3?{??
  • ?????private?static?Map<String,Singleton3>?map?=?new?HashMap<String,Singleton3>();??
  • ?????static{??
  • ?????????Singleton3?single?=?new?Singleton3();??
  • ?????????map.put(single.getClass().getName(),?single);??
  • ?????}??
  • ?????//保護的默認構造子??
  • ?????protected?Singleton3(){}??
  • ?????//靜態工廠方法,返還此類惟一的實例??
  • ?????public?static?Singleton3?getInstance(String?name)?{??
  • ?????????if(name?==?null)?{??
  • ?????????????name?=?Singleton3.class.getName();??
  • ?????????????System.out.println("name?==?null"+"--->name="+name);??
  • ?????????}??
  • ?????????if(map.get(name)?==?null)?{??
  • ?????????????try?{??
  • ?????????????????map.put(name,?(Singleton3)?Class.forName(name).newInstance());??
  • ?????????????}?catch?(InstantiationException?e)?{??
  • ?????????????????e.printStackTrace();??
  • ?????????????}?catch?(IllegalAccessException?e)?{??
  • ?????????????????e.printStackTrace();??
  • ?????????????}?catch?(ClassNotFoundException?e)?{??
  • ?????????????????e.printStackTrace();??
  • ?????????????}??
  • ?????????}??
  • ?????????return?map.get(name);??
  • ?????}??
  • ?????//一個示意性的商業方法??
  • ?????public?String?about()?{??????
  • ?????????return?"Hello,?I?am?RegSingleton.";??????
  • ?????}??????
  • ?????public?static?void?main(String[]?args)?{??
  • ?????????Singleton3?single3?=?Singleton3.getInstance(null);??
  • ?????????System.out.println(single3.about());??
  • ?????}??
  • ?}??


  • 餓漢式和懶漢式區別

    從名字上來說,餓漢和懶漢,

    餓漢就是類一旦加載,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,

    而懶漢比較懶,只有當調用getInstance的時候,才回去初始化這個單例。


    另外從以下兩點再區分以下這兩種方式:

    1、線程安全:


    餓漢式天生就是線程安全的,可以直接用于多線程而不會出現問題,

    懶漢式本身是非線程安全的,為了實現線程安全有幾種寫法,分別是上面的1、2、3,這三種實現在資源加載和性能方面有些區別。


    2、資源加載和性能:

    ? ? ? ?餓漢式在類創建的同時就實例化一個靜態對象出來,不管之后會不會使用這個單例,都會占據一定的內存,但是相應的,在第一次調用時速度也會更快,因為其資源已經初始化完成;

    ? ? ? 而懶漢式顧名思義,會延遲加載,在第一次使用該單例的時候才會實例化對象出來,第一次調用時要做初始化,如果要做的工作比較多,性能上會有些延遲,之后就和餓漢式一樣了。


    什么是線程安全?

    ? ? ? ? 如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。

    ? ? ? ?或者說:一個類或者程序所提供的接口對于線程來說是原子操作,或者多個線程之間的切換不會導致該接口的執行結果存在二義性,也就是說我們不用考慮同步的問題,那就是線程安全的。

    總結

    以上是生活随笔為你收集整理的Java 进阶——单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。