注意:
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...