設計模式 單例模式 餓漢式和懶漢式

2021-10-17 03:30:50 字數 2913 閱讀 4937

單例模式

單例模式要求類能夠有返回物件乙個引用(同乙個)和乙個獲得該例項的方法(必須是靜態方法,通常使用getinstance這個名稱)

單例的實現主要是通過以下步驟:

(1)將構造方法私有化,使其不能在類的外部通過new關鍵字例項化該類物件。

(2)在該類內部產生乙個唯一的例項化物件,並且將其封裝為private static型別。

(3)定義乙個靜態方法返回這個唯一物件。

注意事項

單例模式在多執行緒的應用場合下必須小心使用。如果當唯一例項尚未建立時,有兩個執行緒同時呼叫建立方法,那麼它們同時沒有檢測到唯一例項的存在,從而同時各自建立了乙個例項,這樣就有兩個例項被構造出來,從而違反了單例模式中例項唯一的原則。 解決這個問題的辦法是為指示類是否已經例項化的變數提供乙個互斥鎖(雖然這樣會降低效率)。

餓漢式

public

class

singleton

//構造方法私有

public

static singleton getinstance()

}

由於餓漢模式是不管程式是否需要該例項物件,都會進行建立,比較浪費資源。由此提出了懶漢模式。即就是:當程式中需要使用該例項物件時,才進行建立該例項物件。但此過程會涉及到多執行緒併發問題。

懶漢式

public

class

singleton

public

static singleton getinstance()

return singleton;

}}

這種寫法起到了懶載入的效果,但只能在單執行緒下使用。如果在多執行緒下,乙個執行緒進入了 if (singleton == null) 判斷語句塊,還未來得及往下執行,另乙個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以在多執行緒環境下不可使用這種方式。

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

public

class

singleton

public

static

synchronized singleton getinstance()

return singleton;

}}

解決上面第三種實現方式的執行緒不安全問題,做個執行緒同步就可以了,於是就對 getinstance() 方法進行了執行緒同步。

缺點:同步效率低,每個執行緒在想獲得類的例項時候,執行getinstance() 方法都要進行同步。而其實這個方法只執行一次例項化**就夠了,後面的想獲得該類例項,直接 return 就行了。

懶漢式雙檢鎖

public

class

singleton

public

static singleton getinstance()

}}return singleton;

}}

這種方式跟餓漢式方式採用的機制類似,但又有不同。兩者都是採用了類裝載的機制來保證初始化例項時只有乙個執行緒。不同的地方在餓漢式方式是只要 singleton 類被裝載就會例項化,沒有懶載入的作用,而靜態內部類方式在 singleton 類被裝載時並不會立即例項化,而是在需要例項化時,呼叫 getinstance 方法,才會裝載 singletoninstance 類,從而完成 singleton 的例項化。

類的靜態屬性只會在第一次載入類的時候初始化,所以在這裡,jvm 幫助我們保證了執行緒的安全性,在類進行初始化時,別的執行緒是無法進入的。

優點:避免了執行緒不安全,延遲載入,效率高。

缺點:這樣還不行,因為

singleton =

newsingleton()

;//不是乙個原子操作

/* 1.分配記憶體空間

2.執行構造方法

3.把這個物件指向這個空間

jvm存在指令重排

123132 此時singleton還沒有完成構造

*/

再加入volatile關鍵字,防止指令重排就可以

public

class

singleton

public

static singleton getinstance()

}}return singleton;

}}

懶漢式三重檢查

public

class

lazyman

else}}

private

volatile

static lazyman lazyman;

public

static lazyman getinstance()

}}return lazyman;

}public

static

void

main

(string[

] args)

throws illegalacces***ception, instantiationexception, nosuchmethodexception, invocationtargetexception, nosuchfieldexception

}

這種方式可以避免通過反獲取該物件的無參建構函式,但是,只需要獲取設定標誌位的欄位名,通過getdeclaredfield方法就可以獲得該欄位,通過setaccessible方法就可以篡改該欄位屬性,一樣來拿無引數構造就行,無視標誌位,直接建立新物件,此時發生單例模式物件並不單一。

設計模式 單例模式 餓漢式,懶漢式

餓漢式 將物件的實現提前準備好,物件指向的記憶體只能有乙個。public class singlection1 餓漢式單例實現 將物件的實現提前準備好 private static final singlection1 single1 new singlection1 靜態工廠 public sta...

單例設計模式 餓漢式和懶漢式

單例設計模式 餓漢式 是執行緒安全的 class person public static person getinstance 單例設計模式 簡潔版 此時person類是單例設計模式,屬於餓漢式 public class test class person 全域性靜態常量 public stati...

單例設計模式 餓漢式和懶漢式

1.什麼是單例設計模式?單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類乙個類只有乙個例項。即乙個類只有乙個物件例項。具體實現 需要 1 將構造方法私有化,使其不能在類的外部通過new關鍵字例項化該類物件。2 在該類內部產生...