設計模式 單例模式

2021-07-14 18:37:08 字數 2721 閱讀 7232

public

class

singleton

public

static singleton getinstance()

return instance;

}}

在多執行緒模式會出現問題,在判斷是否為空的情況下,假如乙個執行緒進來,判斷為空,還沒new物件的時候,另外乙個執行緒進來,也是為空,於是也進去new物件,所以導致獲取的單例物件不同,產生執行緒安全問題。

public

class

singleton

public

static

synchronized singleton getinstance()

return instance;

}}

getinstance方法上面加了synchronized修飾,而且還是static方法,所以這裡鎖住的是當前類的class,所以能夠保證執行緒安全,但是再所有呼叫singleton.getinstance()的時候,都要給獲取物件鎖去操作,太耗效能。

public

class

singleton

public

static singleton getinstance()

}

這種方式基於classloder機制避免了多執行緒的同步問題,不過,instance在類裝載時就例項化,雖然導致類裝載的原因有很多種,在單例模式中大多數都是呼叫getinstance方法, 但是也不能確定有其他的方式(或者其他的靜態方法)導致類裝載,這時候初始化instance顯然沒有達到lazy loading的效果。

public

class

singleton

private

singleton()

public

static singleton getinstance()

}

其實跟第三種差不多,static靜態**塊也是在singleton類載入的時候呼叫。

public

class

singleton

private

singleton()

public

static

final singleton getinstance()

}

這種方式同樣利用了classloder的機制來保證初始化instance時只有乙個執行緒,它跟第三種和第四種方式不同的是(很細微的差別):第三種和第四種方式是只要singleton類被裝載了,那麼instance就會被例項化(沒有達到lazy loading效果),而這種方式是singleton類被裝載了,instance不一定被初始化。因為singletonholder類沒有被主動使用,只有顯示通過呼叫getinstance方法時,才會顯示裝載singletonholder類,從而例項化instance。想象一下,如果例項化instance很消耗資源,我想讓他延遲載入,另外一方面,我不希望在singleton類載入時就例項化,因為我不能確保singleton類還可能在其他的地方被主動使用從而被載入,那麼這個時候例項化instance顯然是不合適的。這個時候,這種方式相比第三和第四種方式就顯得很合理。

public

enum singleton

這種方式的好處主要是:1.執行緒安全 2.不會因為序列化而產生新例項 3.防止反射攻擊

預設列舉例項的建立是執行緒安全的.(建立列舉類的單例在jvm層面也是能保證執行緒安全的),所以不需要擔心執行緒安全的問題.

關於序列化.

以往的單例實現了序列化介面,那麼就再也不能保持單例的狀態了.因為readobject()方法一直返回乙個

新的物件.使用radresolve()來避免此情況發生.

//readresolve to prevent another instance of singleton

private object readresolve()

參考:

public

class

singleton

public

static singleton getinstance()}}

return instance;

}}

也就是第一種方式的執行緒安全版本,第二種方式的公升級版,正如第一種方式而言,假設兩個執行緒,乙個執行緒判斷為空,進入,還沒賦值,另外乙個執行緒判斷為空,進入,但是只有乙個執行緒能獲取到當前類的class鎖,所以其中乙個執行緒進入賦值new物件,然後返回,這個同步塊執行後,另外乙個執行緒也拿到鎖,進入,判斷instance有值了,所以跳出if,return instance的值,這種方式還是比較好,注意這裡修飾instance屬性加了修飾符volatile

在jdk1.5之後,雙重檢查鎖定才能夠正常達到單例效果。因為volatile是jdk1.5才開始提供的。

其實總的來說,是五種寫法:懶漢,惡漢,雙重校驗鎖,列舉和靜態內部類

個人推薦,如果不在乎是否延遲載入的問題,可以使用第三種,簡單粗暴,執行緒安全。第五種和第七種是主流的解決方式,第六種是非主流方式,優點是**簡短。

設計模式 單例模式

單例模式 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的序列生成等.但單例的使用需要謹慎,特別是在需要作負載均衡的地方,因為這種程式級的單例模式實際上只能保證在乙個應用中為單例.如果被多個應用載入,還是會...