單例模式總結

2021-09-29 09:58:09 字數 3506 閱讀 7289

所謂類的單例設計模式,就是採取一定的方法保證在整個的軟體系統中,對某個類

只能存在乙個物件例項,並且該類只提供乙個取得其物件例項的方法(靜態方法)。

單例模式有八種方式:

1) 餓漢式(靜態常量)

2) 餓漢式(靜態**塊)

懶漢式(執行緒不安全)

懶漢式(執行緒安全,同步方法)

懶漢式(執行緒安全,同步**塊)

6) 雙重檢查

7) 靜態內部類

8) 列舉

餓漢式(靜態常量)應用例項

步驟如下

構造器私有化 (防止 new )

類的內部建立物件

向外暴露乙個靜態的公共方法。getinstance

**實現

class

hungrysingleton

;//內部建立乙個hungrysingleton的例項

private

static hungrysingleton instance =

newhungrysingleton()

;//提供乙個public 的靜態方法,可以返回例項

public

static hungrysingleton getinstance()

}

優缺點

優點:寫法簡單,類裝載的時候就完成了例項化,避免了執行緒同步的問題

缺點: 在類裝載的時候就完成了例項化,沒有達到lazy loading的效果,如果沒用過這個例項,會造成記憶體的浪費

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

結論:這種單例模式可用可能造成記憶體浪費

餓漢式 通過反射或者序列化會破壞單例

class

singleton

//判斷是否有singleton

public

static singleton getinstance()

return singlenton;

}}

優缺點說明

起到了lazy loading的效果,但是只能在單執行緒下使用。

如果在多執行緒下,乙個執行緒進入了if (singleton == null)判斷語句塊,還未來得及

往下執行,另乙個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以

在多執行緒環境下不可使用這種方式

結論:在實際開發中,不要使用這種方式.

class

singleton

//加入同步**,解決執行緒不安全的問題

public

static

synchronized singleton getinstance()

return singlenton;

}}

優缺點說明

解決了執行緒不安全問題

效率太低了,每個執行緒在想獲得類的例項時候,執行getinstance()方法都要進行

同步。而其實這個方法只執行一次例項化**就夠了,後面的想獲得該類例項,

直接return就行了。方法進行同步效率太低

class

singleton

//雙重判斷

public

static singleton getinstance()

}}return singlenton;

}}

優缺點說明

double-check概念是多執行緒開發中常使用到的,如**中所示,我們進行了兩

次if (singleton == null)檢查,這樣就可以保證執行緒安全了。

這樣,例項化**只用執行一次,後面再次訪問時,判斷if (singleton == null),

直接return例項化物件,也避免的反覆進行方法同步.

執行緒安全;延遲載入;效率較高

為什麼乙個if不行: 假如乙個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,

另乙個執行緒也通過了這個判斷語句,這時便會產生多個例項

class singleton

private static class singletoninstance

public static singleton getinstance()

}

優缺點說明

這種方式採用了類裝載的機制來保證初始化例項時只有乙個執行緒。

靜態內部類方式在singleton類被裝載時並不會立即例項化,而是在需要例項化

時,呼叫getinstance方法,才會裝載singletoninstance類,從而完成singleton的

例項化。

類的靜態屬性只會在第一次載入類的時候初始化,所以在這裡,jvm幫助我們

保證了執行緒的安全性,在類進行初始化時,別的執行緒是無法進入的。

優點:避免了執行緒不安全,利用靜態內部類特點實現延遲載入,效率高

結論:推薦使用.

enum singleton

}

public

enum singleton

public

void

setobjname

(string objname)

public

static

void

main

(string[

] args)

}catch

(exception e)

}}

firstname

secondname

secondname

secondname

該實現可以防止反射攻擊。在其它實現中,通過 setaccessible() 方法可以將私有建構函式的訪問級別設定為 public,然後呼叫建構函式從而例項化物件,如果要防止這種攻擊,需要在建構函式中新增防止多次例項化的**。該實現是由 jvm 保證只會例項化一次,因此不會出現上述的反射攻擊。

該實現在多次序列化和序列化之後,不會得到多個例項。而其它實現需要使用 transient 修飾所有字段,並且實現序列化和反序列化的方法。

單例模式總結

三種實現單例模式的對比 1.volatile關鍵字不但可以防止指令重排,也可以保證執行緒訪問的變數值是 主記憶體中的最新值 有關volatile的詳細原理,我在以後的漫畫中會專門講解。2.使用列舉實現的單例模式,不但可以防止利用反射強行構建單例物件 可以而且在列舉類物件被 反序列化 的時候,保證反序...

單例模式總結

單例模式的使用有乙個必要的條件,在乙個系統要求乙個類只有乙個例項時才應當使用單例模式。在懶漢式單例的時候為什麼要進行執行緒的控制呢?package 單例模式.懶漢模式 public class lazysingleton synchronized public lazysingleton getin...

單例模式總結

一 單例模式 singleton pattern 單例模式只涉及到乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。並且提供了訪問其唯一物件的方式,可以直接訪問,不需要在外部例項化該類的物件。1 單例模式可總結為以下三點 1 構造方法使用private私有化 保證外部無法new出例項...