Java單例的7種寫法,你會幾種?
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
? 作者?|??唯一浩哥
來源 |? urlify.cn/bYzyYb
一、概述
Java中單例有7種寫法,這個是在面試中經(jīng)常被問到的內(nèi)容,而且有時候還要求手寫單例實現(xiàn)方式。所以我們有必要認真的了解一下這七種寫法。
二、七種實現(xiàn)
2.1 懶漢式——線程不安全
public?class?SingletonOne?{
????public?static?SingletonOne?singleton;
????private?SingletonOne()?{}
????public?static?SingletonOne?getSingleton()?{
????????if?(singleton?==?null)
????????????return?new?SingletonOne();
????????return?singleton;
????}
}
懶漢式實現(xiàn)了懶加載,但是線程不安全,基本不會使用。
2.2 懶漢式——線程安全
public?class?SingletonTwo?{
????public?static?SingletonTwo?singleton;
????private?SingletonTwo()?{}
????public?static?synchronized?SingletonTwo?getSingleton()?{
????????if?(singleton?==?null)
????????????return?new?SingletonTwo();
????????return?singleton;
????}
}
在第一種的基礎上加了個synchronized,保證線程安全,同時實現(xiàn)了懶加載,只是效率不高。
2.3 餓漢式
public?class?SingletonThree?{
????public?static?SingletonThree?singleton?=?new?SingletonThree();
????private?SingletonThree?()?{?}
????public?static?SingletonThree?getSingleton()?{
????????return?singleton;
????}
}
由于實例優(yōu)先提供,不存在線程安全問題,但是沒有實現(xiàn)懶加載。
2.4 餓漢式——變種
public?class?SingletonFour?{
????public?static?SingletonFour?singleton;
????static?{
????????singleton?=?new?SingletonFour();
????}
????private?SingletonFour?()?{?}
????public?static?SingletonFour?getSingleton()?{
????????return?singleton;
????}
}
其實和之前的一樣,僅僅是將單例的創(chuàng)建挪到了靜態(tài)塊。
2.5 靜態(tài)內(nèi)部類式
public?class?SingletonFive?{
????private?static?class?SingletonHolder?{
????????private?static?SingletonFive?singleton?=?new?SingletonFive();
????}
????private?SingletonFive?()?{}
????public?static?final?SingletonFive?getSingleton(){
????????return?SingletonHolder.singleton;
????}
}
靜態(tài)內(nèi)部類保證了懶加載,單例實例優(yōu)先提供又保證了線程安全性,較實用。
2.6 枚舉式
public?enum?SingletonSix?{
????SINGLETON;
}
枚舉的天然特性保證了單例,天然的私有構(gòu)造器,天然的線程安全性,未被大規(guī)模使用的原因是枚舉出現(xiàn)的有點晚。
2.7 雙重校驗鎖式
public?class?SingletonSeven?{
????private?static?volatile?SingletonSeven?singleton;
????private?SingletonSeven()?{}
????public?static?SingletonSeven?getSingleton(){
????????if?(singleton?==?null)?{
????????????synchronized?(SingletonSeven.class)?{
????????????????if?(singleton?==?null)
????????????????????return?new?SingletonSeven();
????????????}
????????}
????????return?singleton;
????}
}
注意:
volatile的使用,為了防止暴露一個未初始化的不完整單例實例;
雙重判空校驗,第一個判斷避免了頻繁的加鎖,第二個判斷可以攔住多余的創(chuàng)建實例的線程;
加鎖,保證了線程安全(只有一個實例)
這種實現(xiàn)方式是經(jīng)常出現(xiàn)在面試題中的,而且經(jīng)常會要求手寫。
三、總結(jié)
上面羅列的7種設計模式中第1種線程不安全,可以排除在外,第3、4種其實是一種,這樣下來其實可以簡化為5種方式:懶漢、餓漢、靜態(tài)內(nèi)部類、枚舉、雙重校驗鎖。
粉絲福利:實戰(zhàn)springboot+CAS單點登錄系統(tǒng)視頻教程免費領取
???
?長按上方微信二維碼?2 秒 即可獲取資料
感謝點贊支持下哈?
評論
圖片
表情
