五種基本單例模式

2021-10-18 06:20:46 字數 3353 閱讀 9163

注意:

1、單例類只能在乙個jvm例項中有乙個例項。

2、單例類必須自己建立自己的唯一例項。

3、單例類必須給所有其他物件提供這一例項。

接下來我們介紹一下我們常見到的幾種單例模式:

正如其名"餓漢" ,類載入的時候就例項化,並且建立單例物件。優點: 先天性執行緒安全 當類初始化的時候 該物件就會被建立

缺點 : 如果專案中使用過多的餓漢式就會發生問題,專案啟動會很慢,存放在方法區中占用記憶體較大

public

class

demo1

public

static demo1 getinstance()

}

只有在需要的時候才會載入 但是在多執行緒的情況下 會出現執行緒安全的問題. 例項物件可能被初始化多次

public

class

demo2

public

static demo2 getinstance()

return singleton;

}}

對於餓漢式它會存在,在多執行緒的情況下,執行緒不安全的問題,例項化的物件(單例物件)可能被例項化多次,這裡我們做乙個測試

public

class

test})

.start()

;}}}

public

class

demo2

public

static demo2 getinstance()

catch

(exception e)

singleton =

newdemo2()

;}return singleton;

}}

結果:

thread-14,單例模式.service.懶漢式.demo2@32b9f1f0

thread-10,單例模式.service.懶漢式.demo2@7070e0ed

thread-4,單例模式.service.懶漢式.demo2@1ea98862

thread-7,單例模式.service.懶漢式.demo2@294eb59e

thread-3,單例模式.service.懶漢式.demo2@26dc9ee3

thread-1,單例模式.service.懶漢式.demo2@5e0d2717

thread-27,單例模式.service.懶漢式.demo2@b20b63

thread-6,單例模式.service.懶漢式.demo2@4b0d0bfe

thread-16,單例模式.service.懶漢式.demo2@3e81761

thread-0,單例模式.service.懶漢式.demo2@7b32301d

thread-8,單例模式.service.懶漢式.demo2@7b32301d

thread-9,單例模式.service.懶漢式.demo2@7b32301d

thread-11,單例模式.service.懶漢式.demo2@21ed9a86

對於多執行緒的情況下,我們對於懶漢式問題可以給它加鎖,來保證執行緒同步

public

synchronized

static demo2 getinstance()

catch

(exception e)

singleton =

newdemo2()

;}return singleton;

}

這樣加鎖可以保證懶漢式在多執行緒情況下的執行緒安全問題,但是有乙個致命的缺點就是加鎖在高併發的情況下,會影響程式的執行效率.那我們如何保證執行緒安全的情況下,加快程式執行的效率呢 ,這裡我們介紹一種雙重檢驗鎖。

什麼是雙重檢驗鎖呢,雙重檢驗鎖是為了解決懶漢式 對於讀和寫都加鎖的問題,在單例模式中,我們只有第一次訪問該物件的時候需要加鎖,物件才需要例項化,之後再次訪問我們就沒有必要再去加鎖,只是讀的操作。我們可以在物件建立的時候進行雙重判斷,來保證執行緒安全,並且提高執行效率.

public

class

demo3

system.out.

println

("初始化雙重檢驗鎖");

}/*只有在需要的時候才會載入 但是在多執行緒的情況下 會出現執行緒安全的問題

例項物件可能被初始化多次

*/public

synchronized

static demo3 getinstance()

throws exception }}

return singleton;

}}

public

class

singleton

private

static

class

singletonholer

public

static singleton getinstance()

}

靜態內部類的優點是:外部類載入時並不需要立即載入內部類,內部類不被載入則不去初始化instance,故而不佔記憶體。即當singleton第一次被載入時,並不需要去載入singletonholer,只有當getinstance()方法第一次被呼叫時,才會去初始化instance,第一次呼叫getinstance()方法會導致虛擬機器載入singletonholer類,這種方法不僅能確保執行緒安全,也能保證單例的唯一性,同時也延遲了單例的例項化。個人認為是懶漢式和餓漢式的公升級版 ,這裡推薦大家一篇部落格,博主對於靜態內部類的實現,講的比較詳細: 深入理解單例模式:靜態內部類單例原理

public

enum demo4

}

測試類

public

class

test}/*

add方法...

add方法...

true

*/

在列舉方式實現的單例模式中,在最終編譯後的class檔案上,是將enum轉化為乙個類,例如上述的例子裡,這裡我們使用jclasslib工具來檢視demo4的位元組碼檔案

);來操作add方法

五種單例模式

import settings class mysql instance none 原始狀態設為none def init self,ip,port self.ip ip self.port port classmethod deffrom conf cls if cls.instance is n...

五種單例模式

1 餓漢模式 public class ehansingleton 提供獲取單例物件的方法 public static ehansingleton getinstance 2 懶漢式 懶漢式 public class lanhansingleton 提供獲取單例物件的方法 增加 synchroniz...

五種單例模式實現

public class hunger private final static hunger hunger newhunger public static hunger getinstance 多個執行緒安全,但無法進行懶載入,如果類成員很多,則占用的資源比較多 public class lazy...