單例模式

單例模式(Singleton Pattern):

Ensure a class has only one instance,and provide a global point of access to it

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

一、單例模式特點:

1、單例類只能有一個實例。
  
 2、單例類必須自己創建自己的唯一實例。
   3、單例類必須給所有其他對象提供這一實例。

二、單例模式目的:

得到一個類只可創建一個對象(並提供一個訪問它的全局訪問點)

三、單例模式應用場景

配置文件、網絡令牌,Mybatis中創建sqlSession


三、單例模式的實現(如下代碼):

1、構造函數私有化,不允許外部直接創建對象(構造函數私有化的類不允許被繼承)

2、定義私有的靜態成員(唯一實例instance)

3、定義公有靜態方法(用於獲取實例)


a、餓漢模式

在類初始化時,已經自行實例化 

餓漢式在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不再改變,所以天生是線程安全的。



b、懶漢模式

Singleton通過將構造方法限定爲private避免了類在外部被實例化,在同一個虛擬機範圍內,Singleton的唯一實例

只能通過getInstance()方法訪問。




懶漢模式線程不安全,於是,我們找到下面三種方式的改變

(1)加同步(每次都要同步,會影響性能)

(2)雙重鎖形式,檢查鎖定

在getInstance中做了兩次null檢查,確保了只有第一次調用單例的時候纔會做同步,這樣也是線程安全的,

同時避免了每次都同步的性能損耗



(3)靜態內部類

利用了classloader的機制來保證初始化instance時只有一個線程,所以也是線程安全

因爲Java機制規定,內部類Holder只有在getInstance()方法第一次調用的時候纔會被加載(實現了lazy),

而且其加載過程是線程安全的(實現線程安全)。內部類加載的時候實例化一次instance。


測試



四、懶漢模式和餓漢模式的區別

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

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


        2、餓漢模式加載類時比較慢,但運行時獲取對象速度比較快,線程安全

     懶漢模式加載類時比較快,但運行時獲取對象速度比較慢,線程不安全


補充:

一個類或者程序所提供的接口對於線程來說是原子操作,或者多個線程之間的切換不會導致該接口的執行結果

存在二義性,也就是說我們不用考慮同步的問題,那就是線程安全的。


發佈了51 篇原創文章 · 獲贊 45 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章