設計模式 單例模式

2021-08-20 14:47:59 字數 1709 閱讀 4379

餓漢式單例

public class singleton ;

public static singleton getinstance()

}

執行緒安全的單例

public class singleton ;

public static synchronized singleton getinstance()

}

單例的雙檢鎖

public class singleton ;

public static singleton getinstance2()

}} return singleton;

}}

為何要使用雙重檢查鎖定呢?上文已經大概說了一下。

考慮這樣一種情況,就是有兩個執行緒同時到達,即同時呼叫 getinstance() 方法,

此時由於

singleton == null ,所以很明顯,兩個執行緒都可以通過第一重的

singleton == null ,

進入第一重 if 語句後,由於存在鎖機制,所以會有乙個執行緒進入 lock 語句並進入第二重

singleton == null ,

而另外的乙個執行緒則會在 lock 語句的外面等待。

而當第乙個執行緒執行完 new 

singleton()語句後,便會退出鎖定區域,此時,第二個執行緒便可以進入 lock 語句塊,

此時,如果沒有第二重

singleton == null 的話,那麼第二個執行緒還是可以呼叫 new 

singleton ()語句,

這樣第二個執行緒也會建立乙個

singleton例項,這樣也還是違背了單例模式的初衷的,

所以這裡必須要使用雙重檢查鎖定。

細心的朋友一定會發現,如果我去掉第一重 singleton == null ,

程式還是可以在多執行緒下完好的執行的,

考慮在沒有第一重 singleton == null 的情況下,

當有兩個執行緒同時到達,此時,由於 lock 機制的存在,第乙個執行緒會進入 lock 語句塊,並且可以順利執行 new singleton(),

當第乙個執行緒退出 lock 語句塊時, singleton 這個靜態變數已不為 null 了,所以當第二個執行緒進入 lock 時,

還是會被第二重 singleton == null 擋在外面,而無法執行 new singleton(),

所以在沒有第一重 singleton == null 的情況下,也是可以實現單例模式的?那麼為什麼需要第一重 singleton == null 呢?

這裡就涉及乙個效能問題了,因為對於單例模式的話,new singleton()只需要執行一次就 ok 了,

而如果沒有第一重 singleton == null 的話,每一次有執行緒進入 getinstance()時,均會執行鎖定操作來實現執行緒同步,

這是非常耗費效能的,而如果我加上第一重 singleton == null 的話,

那麼就只有在第一次,也就是 singletton ==null 成立時的情況下執行一次鎖定以實現執行緒同步,

而以後的話,便只要直接返回 singleton 例項就 ok 了而根本無需再進入 lock 語句塊了,這樣就可以解決由執行緒同步帶來的效能問題了。

引用兩篇文章

設計模式 單例模式

單例模式 singleton pattern 是乙個比較簡單的模式,其定義如下 ensure a class has only one instance,and provide a golbal point of acess to it.確保某乙個類只有乙個例項,而且自行例項化並且向整個系統提供這個...

設計模式 單例模式

class testsingleton static public function instance return self testsingleton private function clone public function setsinvar sinvar public function ...

設計模式 單例模式

單例模式的目的是保證類在系統中只被例項化一次,由該唯一的例項來為系統提供服務.單例模式主要用於保證服務的統一,比如獲取統一的編號服務,模仿oracle的序列生成等.但單例的使用需要謹慎,特別是在需要作負載均衡的地方,因為這種程式級的單例模式實際上只能保證在乙個應用中為單例.如果被多個應用載入,還是會...