java 单例 实现_java 实现单例的各种方式
概述
上一篇日志中,我們介紹了單例模式的概念和基礎(chǔ)的應(yīng)用
本節(jié)中,我們就來(lái)介紹一下?java?語(yǔ)言中如何編寫(xiě)單例模式類(lèi)
只適合單線程環(huán)境的單例模式
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
這是單例模式的最簡(jiǎn)單實(shí)現(xiàn),private?的構(gòu)造方法保證了類(lèi)不會(huì)被通過(guò)?new?的方式創(chuàng)建,同時(shí),判斷?instance?是否為?null?保證了單線程環(huán)境下單例模式運(yùn)行的正確性
但是,正如我們反復(fù)強(qiáng)調(diào)的,這種方式是非線程安全的,原因在于,當(dāng)多個(gè)線程并發(fā)執(zhí)行,同時(shí)進(jìn)行判斷?instance?為?null?的操作,而此時(shí)?instance?確實(shí)為?null,那么所有的線程都將去創(chuàng)建一個(gè)單例的對(duì)象,這顯然是我們不希望看到的,那么下面我們就來(lái)解決這個(gè)問(wèn)題
通過(guò)同步鎖實(shí)現(xiàn)線程安全
正如上面提到的,之所以存在線程安全問(wèn)題,主要是因?yàn)榕袛?instance?是否為?null?與對(duì)象的創(chuàng)建是非原子性的,那么,我們只需要用鎖來(lái)保證兩個(gè)操作的原子性即可解決這個(gè)問(wèn)題
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
但是加鎖對(duì)性能是會(huì)造成影響的,在并發(fā)環(huán)境下,當(dāng)一個(gè)線程運(yùn)行到?synchronized?處,獲取鎖進(jìn)入到?instance?的判斷,其他所有的并發(fā)線程都必須在該線程執(zhí)行完?instance?的創(chuàng)建操作后才能夠繼續(xù)執(zhí)行,而事實(shí)上,一旦?instance?被創(chuàng)建,這樣的等待都將會(huì)是白費(fèi)的
雙重校驗(yàn)鎖
雙重校驗(yàn)鎖對(duì)上面的例子進(jìn)行了優(yōu)化
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
一旦對(duì)象被創(chuàng)建,那么程序?qū)⒉粫?huì)去請(qǐng)求獲取鎖而是直接返回?instance
最簡(jiǎn)單的線程安全單例模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
這段代碼看上去非常簡(jiǎn)單,他會(huì)在類(lèi)首次被加載時(shí)創(chuàng)建單例的對(duì)象,jvm?會(huì)保證單例對(duì)象只被創(chuàng)建一次,但是有時(shí)我們僅僅是在代碼中引用了這個(gè)類(lèi),或者僅僅調(diào)用了這個(gè)類(lèi)中的其他方法,我們并不希望在我們還不需要通過(guò)?getInstance?方法獲取對(duì)象的時(shí)候,對(duì)象就已經(jīng)被創(chuàng)建了,這是這種方式的主要問(wèn)題
靜態(tài)內(nèi)部類(lèi)
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
這種方式解決了上一種方式所存在的問(wèn)題,僅在?getInstance?方法被調(diào)用時(shí),對(duì)象才會(huì)被創(chuàng)建
使用枚舉
public enum SingletonEnum {
BOOM_MAZE_FACTORY(new BoomMazeFactory()),
STANDARD_MAZE_FACTORY(new StandardMazeFactory()),
;
private MazeFactory mazeFactory;
public MazeFactory getMazeFactory() {
return mazeFactory;
}
SingletonEnum(MazeFactory mazeFactory) {
this.mazeFactory = mazeFactory;
}
}
由于枚舉在項(xiàng)目中并不會(huì)被常常用到,這樣的用法就更加難得一見(jiàn)了,而事實(shí)上,這才是最推薦的用法
微信公眾號(hào)
歡迎關(guān)注微信公眾號(hào),以技術(shù)為主,涉及歷史、人文等多領(lǐng)域的學(xué)習(xí)與感悟,每周三到七篇推文,只有全部原創(chuàng),只有干貨沒(méi)有雞湯
標(biāo)簽
技術(shù)帖
技術(shù)分享
java
singleton
設(shè)計(jì)模式
模式
設(shè)計(jì)
單例
總結(jié)
以上是生活随笔為你收集整理的java 单例 实现_java 实现单例的各种方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: msci指数是什么意思?
- 下一篇: java emptylist_Java之
