設計模式之單例設計模式

2022-07-08 20:03:12 字數 2633 閱讀 5256

設計模式之單例設計模式

單例模式的實現目標就是保證乙個類有且僅有乙個例項,當然這也是有前提的,就是由同乙個classloader載入的這個類有且僅有乙個物件,如果這裡類由不同的classloader載入,則會產生多個物件。

(一) 單執行緒下的單例設計模式

(1)餓漢式

public

class

singleton

public

static

singleton getinstance()

}

(2)懶漢式

public

class

singleton

public

static

singleton getinstance()

return

instance;

}}

(二)多執行緒下的單例設計模式

在多執行緒環境下,餓漢式單例模式是執行緒安全的。但懶漢式單例模式getinstance()的if語句形成了乙個if-then-act操作,它並不是乙個原子操作,因此可能引發執行緒安全問題,建立多個物件,破壞單例性。

很容易讓我們想到的是,採用同步(synchronized)的方式加鎖,保證執行緒安全,如下所示:

/**

* 基於簡單加鎖的單例模式實現

* @author

administrator *

*/public

class

singleton

public

static

singleton getinstance()

}return

instance;

}}

這種方法的單例模式固然是執行緒安全的,但是每個執行緒在執行getinstance()方法時,都必須申請鎖,增加了系統的開銷,降低了效率,而我們需要的僅僅是第一次建立物件時加鎖即可,之後所有執行緒可併發獲得該物件。於是我們採用雙重檢查鎖定的方式實現單例模式:

/**

* 基於雙重檢查鎖定的單例模式實現(錯誤**)

* @author

administrator *

*/public

class

singleton

public

static

singleton getinstance() }}

return

instance;

}}

看似這種做法很巧妙解決了多執行緒環境下的單例模式的安全問題。其實不然,上述**中的語句①可分解為三個子操作,分配物件所需的記憶體空間(子操作①)、初始化物件(子操作②)和將物件引用傳入棧內的變數。想象一下這樣乙個場景,執行緒t1通過了第一次null == instance的判斷,執行緒t1持有鎖進行了第二次判斷,此時執行緒t1進入了臨界區,根據臨界區重排序規則:臨界區內的**執行被重排序,因此,子操作③可能排在了子操作②之前,因此當執行緒t1執行到操作③時,由於此時操作②並沒有執行,因此instance物件並沒有初始化完成,但是instance以不為空,就在此時,執行緒t2執行了第一次null==instance判斷,隨然instance並未初始化完成,但以不是 null,所以直接返回給執行緒t2 instance物件,這樣執行緒t2呼叫instance物件時就可能產生未知的錯誤。所以上述**是不正確的。

需要將instance變數的採用volatile修飾,禁止其寫操作與該操作之前的任何讀、寫操作進行重排序,因此,用volatile修飾instance相當於禁止了子操作②(對物件進行初始化的寫操作)重拍到子操作③(對物件引用寫入共享變數的子操作)之前,保證了執行緒讀到的instance都是初始化完成的instance。

/**

* 基於雙重檢查鎖定的單例模式實現(正確實現)

* @author

administrator *

*/public

class

singleton

public

static

singleton getinstance() }}

return

instance;

}}

考慮到雙重檢測鎖定法實現上容易出錯,我們選擇另外一種可以延遲載入的單例模式:基於靜態內部類的單例模式。

靜態內部類只有在初次訪問時才會觸發虛擬機器對該類進行初始化,因此singletoninstanceholder.instance會初始化靜態內部類 

/**

* 基於靜態內部類的單例模式實現

* @author

administrator *

*/public

class

singleton

private

static

class

singletoninstanceholder

public

static

singleton getinstance()

}

也可通過列舉來實現執行緒安全的單例模式:

public

enum

singleton

public

void

dosomething()

}

設計模式之 單例設計模式

單例設計模式 單例設計模式概述 單例模式就是要確保類在記憶體中只有乙個物件,該例項必須自動建立,並且對外提供。優點 在系統記憶體中只存在乙個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷毀的物件單例模式無疑可以提高系統的效能。缺點 沒有抽象層,因此擴充套件很難。職責過重,在一定程式上違背了單一...

設計模式之單例設計模式

singleton 保證乙個類只有乙個例項,並提供訪問它的全域性訪問點 類初始化時,立即載入這個物件 沒有延時載入的優勢 載入類時,天然的是執行緒安全的!private static singletondemo1 instance new singletondemo1 private singlet...

設計模式之單例設計模式

目錄 1.到底什麼是設計模式?2.什麼是單例設計模式?3.單列設計模式的兩種實現方式 餓漢式懶漢式 執行緒不安全 4.執行緒安全的寫法 餓漢式懶漢式 執行緒安全 設計模式可以理解為別人成功的故事,通用的套路,前人的經驗,設計模式是一種思想,沒有具體的實現。打乙個比方 世界上只有乙個太陽,乙個月亮,單...