1 餓漢式(靜態(tài)常量)[可用]
優(yōu)點(diǎn):這種寫法比較簡(jiǎn)單僧免,就是在類裝載的時(shí)候就完成實(shí)例化。避免了線程同步問(wèn)題叫乌。
缺點(diǎn):在類裝載的時(shí)候就完成實(shí)例化娇未,沒(méi)有達(dá)到Lazy Loading的效果责静。如果從始至終從未使用過(guò)這個(gè)實(shí)例,則會(huì)造成內(nèi)存的浪費(fèi)盖桥。
<pre>
public class Singleton{
private static Singleton singleton = new Singleton;
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
</pre>
2 餓漢式(靜態(tài)代碼塊)[可用]
這種方式和上面的方式其實(shí)類似灾螃,只不過(guò)將類實(shí)例化的過(guò)程放在了靜態(tài)代碼塊中,也是在類裝載的時(shí)候揩徊,就執(zhí)行靜態(tài)代碼塊中的代碼腰鬼,初始化類的實(shí)例。優(yōu)缺點(diǎn)和上面是一樣的塑荒。
<pre>
public class Singleton{
private static Singleton singleton;
static {
singleton = new Singleton;
}
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
</pre>
3 懶漢式(線程不安全)[不可用]
這種寫法起到了Lazy Loading的效果熄赡,但是只能在單線程下使用。如果在多線程下齿税,一個(gè)線程進(jìn)入了if (singleton == null)判斷語(yǔ)句塊彼硫,還未來(lái)得及往下執(zhí)行,另一個(gè)線程也通過(guò)了這個(gè)判斷語(yǔ)句凌箕,這時(shí)便會(huì)產(chǎn)生多個(gè)實(shí)例拧篮。所以在多線程環(huán)境下不可使用這種方式。
<pre>
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
</pre>
4 懶漢式(線程安全牵舱,同步方法)[不推薦用]
解決上面第三種實(shí)現(xiàn)方式的線程不安全問(wèn)題串绩,做個(gè)線程同步就可以了,于是就對(duì)getInstance()方法進(jìn)行了線程同步芜壁。
缺點(diǎn):效率太低了礁凡,每個(gè)線程在想獲得類的實(shí)例時(shí)候,執(zhí)行g(shù)etInstance()方法都要進(jìn)行同步慧妄。而其實(shí)這個(gè)方法只執(zhí)行一次實(shí)例化代碼就夠了顷牌,后面的想獲得該類實(shí)例,直接return就行了塞淹。方法進(jìn)行同步效率太低要改進(jìn)韧掩。
<pre>
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
</pre>
5 懶漢式(線程安全,同步代碼塊)[不可用]
由于第四種實(shí)現(xiàn)方式同步效率太低窖铡,所以摒棄同步方法疗锐,改為同步產(chǎn)生實(shí)例化的的代碼塊。但是這種同步并不能起到線程同步的作用费彼。跟第3種實(shí)現(xiàn)方式遇到的情形一致滑臊,假如一個(gè)線程進(jìn)入了if (singleton == null)判斷語(yǔ)句塊,還未來(lái)得及往下執(zhí)行箍铲,另一個(gè)線程也通過(guò)了這個(gè)判斷語(yǔ)句雇卷,這時(shí)便會(huì)產(chǎn)生多個(gè)實(shí)例。
<pre>
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
singleton = new Singleton();
}
}
return singleton;
}
}
</pre>
6 雙重檢查[推薦用]
Double-Check概念對(duì)于多線程開(kāi)發(fā)者來(lái)說(shuō)不會(huì)陌生,如代碼中所示关划,我們進(jìn)行了兩次if (singleton == null)檢查小染,這樣就可以保證線程安全了。這樣贮折,實(shí)例化代碼只用執(zhí)行一次裤翩,后面再次訪問(wèn)時(shí),判斷if (singleton == null)调榄,直接return實(shí)例化對(duì)象踊赠。
優(yōu)點(diǎn):線程安全;延遲加載每庆;效率較高筐带。
<pre>
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
</pre>
7 靜態(tài)內(nèi)部類[推薦用]
這種方式跟餓漢式方式采用的機(jī)制類似,但又有不同缤灵。兩者都是采用了類裝載的機(jī)制來(lái)保證初始化實(shí)例時(shí)只有一個(gè)線程伦籍。不同的地方在餓漢式方式是只要Singleton類被裝載就會(huì)實(shí)例化,沒(méi)有Lazy-Loading的作用腮出,而靜態(tài)內(nèi)部類方式在Singleton類被裝載時(shí)并不會(huì)立即實(shí)例化鸽斟,而是在需要實(shí)例化時(shí),調(diào)用getInstance方法利诺,才會(huì)裝載SingletonInstance類富蓄,從而完成Singleton的實(shí)例化。
類的靜態(tài)屬性只會(huì)在第一次加載類的時(shí)候初始化慢逾,所以在這里立倍,JVM幫助我們保證了線程的安全性,在類進(jìn)行初始化時(shí)侣滩,別的線程是無(wú)法進(jìn)入的口注。
優(yōu)點(diǎn):避免了線程不安全,延遲加載君珠,效率高寝志。
<pre>
public class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
</pre>
8 枚舉[推薦用]
借助JDK1.5中添加的枚舉來(lái)實(shí)現(xiàn)單例模式。不僅能避免多線程同步問(wèn)題策添,而且還能防止反序列化重新創(chuàng)建新的對(duì)象材部。可能是因?yàn)槊杜e在JDK1.5中才添加唯竹,所以在實(shí)際項(xiàng)目開(kāi)發(fā)中乐导,很少見(jiàn)人這么寫過(guò)。
優(yōu)點(diǎn):系統(tǒng)內(nèi)存中該類只存在一個(gè)對(duì)象浸颓,節(jié)省了系統(tǒng)資源物臂,對(duì)于一些需要頻繁創(chuàng)建銷毀的對(duì)象旺拉,使用單例模式可以提高系統(tǒng)性能。
缺點(diǎn):當(dāng)想實(shí)例化一個(gè)單例類的時(shí)候棵磷,必須要記住使用相應(yīng)的獲取對(duì)象的方法蛾狗,而不是使用new,可能會(huì)給其他開(kāi)發(fā)人員造成困擾仪媒,特別是看不到源碼的時(shí)候沉桌。
適用場(chǎng)合:需要頻繁的進(jìn)行創(chuàng)建和銷毀的對(duì)象;創(chuàng)建對(duì)象時(shí)耗時(shí)過(guò)多或耗費(fèi)資源過(guò)多规丽,但又經(jīng)常用到的對(duì)象蒲牧;工具類對(duì)象撇贺;頻繁訪問(wèn)數(shù)據(jù)庫(kù)或文件的對(duì)象赌莺。
<pre>
public enum Singleton {
INSTANCE;
public void whateverMethod() {
...
}
}
</pre>
單例模式
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)似谁,“玉大人傲绣,你說(shuō)我怎么就攤上這事」ぃ” “怎么了秃诵?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)塞琼。 經(jīng)常有香客問(wèn)我菠净,道長(zhǎng),這世上最難降的妖魔是什么彪杉? 我笑而不...
- 正文 為了忘掉前任毅往,我火速辦了婚禮,結(jié)果婚禮上派近,老公的妹妹穿的比我還像新娘煞抬。我一直安慰自己,他們只是感情好构哺,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布革答。 她就那樣靜靜地躺著战坤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪残拐。 梳的紋絲不亂的頭發(fā)上途茫,一...
- 那天,我揣著相機(jī)與錄音溪食,去河邊找鬼囊卜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛错沃,可吹牛的內(nèi)容都是我干的栅组。 我是一名探鬼主播,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼枢析,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼玉掸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起醒叁,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤司浪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后把沼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啊易,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年饮睬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了租谈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站矾克,受9級(jí)特大地震影響页慷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胁附,卻給世界環(huán)境...
- 文/蒙蒙 一酒繁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧控妻,春花似錦州袒、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)他匪。三九已至,卻和暖如春夸研,著一層夾襖步出監(jiān)牢的瞬間邦蜜,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓姐扮,卻偏偏與公主長(zhǎng)得像絮供,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茶敏,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 單例模式(Singleton Pattern)是眾多設(shè)計(jì)模式中較為簡(jiǎn)單的一個(gè)壤靶,同時(shí)它也是面試時(shí)經(jīng)常被提及的問(wèn)題,如...
- 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用睡榆,讀取配置文件的內(nèi)容萍肆。 很多應(yīng)用項(xiàng)目袍榆,都有與應(yīng)用相...
- 這又是一個(gè)新的系列啦胀屿,探究各大設(shè)計(jì)模式在開(kāi)發(fā)中必須注意思考的一些問(wèn)題,以及它們的多向使用包雀。 文章結(jié)構(gòu):(1)單例模...
- 概述 單例模式就是保證在整個(gè)應(yīng)用程序的生命周期中宿崭,在任何時(shí)刻露久,被指定的類只有一個(gè)實(shí)例锥忿,并為客戶程序提供一個(gè)獲取該實(shí)...
- 單例模式(Singleton Pattern)是 編程語(yǔ)言中最簡(jiǎn)單的設(shè)計(jì)模式之一哲银。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式...