在寫Spring Boot 2.0.2-webmvc源碼分析系列的文章時(shí)暑中,當(dāng)時(shí)提到了Servlet單例模式挖胃。所以就想著寫一篇文章來介紹以下單例模式辽剧,其實(shí)網(wǎng)上類似這種設(shè)計(jì)模式的文章很多族淮,23種設(shè)計(jì)模式大家可能都看過椭迎,早些時(shí)候自己也都看過彰阴,基本上只對(duì)常用的幾種印象比較深刻瘾敢,其余不常用的差不多都忘記了。既然提到了單例模式,那就仔細(xì)介紹一下簇抵。再加深一下印象庆杜。
單例模式定義:
單例模式,屬于創(chuàng)建類型的一種常用的軟件設(shè)計(jì)模式碟摆。通過單例模式的方法創(chuàng)建的類在當(dāng)前進(jìn)程中只有一個(gè)實(shí)例晃财。
我覺得學(xué)習(xí)設(shè)計(jì)模式,主要可以從以下四個(gè)方面著手典蜕。
1断盛、該設(shè)計(jì)模式的一般使用場(chǎng)景。
2嘉裤、該設(shè)計(jì)模式的實(shí)現(xiàn)郑临。
3、該設(shè)計(jì)模式主要解決的問題及優(yōu)點(diǎn)屑宠。
4厢洞、該設(shè)計(jì)模式的不足之處。
單例模式的一般使用場(chǎng)景典奉,下面列舉常見的幾種:
1躺翻、一般的應(yīng)用系統(tǒng)都有一個(gè)或多個(gè)屬性文件存放系統(tǒng)配置,這樣的應(yīng)用可以使用一個(gè)單例對(duì)象來管理這些屬性文件 卫玖。
2公你、 網(wǎng)站的計(jì)數(shù)器,一般可以使用單例模式實(shí)現(xiàn)假瞬,不然數(shù)據(jù)很難同步陕靠。
3、系統(tǒng)的日志應(yīng)用脱茉,一般可以使用單例模式實(shí)現(xiàn)剪芥,由于共享的日志文件一直處于打開狀態(tài),因?yàn)橹荒苡幸粋€(gè)實(shí)例去操作琴许,否則內(nèi)容不好追加税肪。
4、應(yīng)用的配置信息讀取榜田,一般也使用單例模式益兄,由于配置文件是共享的資源。為了保證數(shù)據(jù)的唯一性箭券,可以使用單例對(duì)象進(jìn)行獲取净捅。
5、線程池的設(shè)計(jì)一般也是采用單例模式邦鲫,由于線程池要對(duì)池中的線程進(jìn)行控制灸叼。
下面簡(jiǎn)單列舉一下使用單例模式的優(yōu)點(diǎn)神汹。
1、 由于單例模式在內(nèi)存中只有一個(gè)實(shí)例古今,所以一定程度上可以減少內(nèi)存消耗屁魏,特別是一個(gè)對(duì)象需要頻繁地創(chuàng)建銷毀時(shí),會(huì)影響系統(tǒng)的性能捉腥,使用單例模式就非常明顯了氓拼。
2、由于單例模式只生成一個(gè)實(shí)例抵碟,當(dāng)一個(gè)對(duì)象實(shí)例需要比較多的資源時(shí)桃漾,如讀取配置信息,則可以通過在應(yīng)用啟動(dòng)時(shí)直接產(chǎn)生一個(gè)單例對(duì)象拟逮,然后放入內(nèi)存的方式來優(yōu)化撬统。
3、單例模式可以避免對(duì)資源的多重占用敦迄,例如一個(gè)寫文件操作恋追,由于只有一個(gè)實(shí)例存在內(nèi)存中,避免對(duì)同一個(gè)資源文件的同時(shí)寫操作罚屋。
4苦囱、單例模式可以在系統(tǒng)設(shè)置全局的訪問點(diǎn),優(yōu)化和共享資源訪問脾猛。
除了優(yōu)點(diǎn)之外撕彤,當(dāng)然也還有一些不足:
1、單例模式?jīng)]有接口猛拴,如果需要擴(kuò)展羹铅,每次都得改代碼。
2愉昆、使用的場(chǎng)景比較單調(diào)睦裳,如果是在多場(chǎng)景不斷變化的實(shí)例對(duì)象最好不要使用單例,數(shù)據(jù)容易出問題撼唾。
下面簡(jiǎn)單介紹以下實(shí)現(xiàn)方式,單例模式的實(shí)現(xiàn)方式有多種哥蔚,不同的實(shí)現(xiàn)方式有不同的優(yōu)缺點(diǎn)倒谷,這里介紹一種生產(chǎn)環(huán)境中常用的實(shí)現(xiàn)方式(靜態(tài)內(nèi)部類實(shí)現(xiàn)),其它幾種方式也不建議使用糙箍,所以就不一一列舉了渤愁,掌握下面這種就夠用了。
public class Singleton {
private Singleton() { }
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
private static class SingletonInstance{
static Singleton INSTANCE = new Singleton();
}
}
使用上面這種單例模式的好處可以保證以下幾點(diǎn):
1深夯、Singleton最多只有一個(gè)實(shí)例抖格,前提是在不考慮反射突破訪問限制的情況下诺苹。
2、保證了即使在高并發(fā)情況下雹拄,也不會(huì)產(chǎn)生多個(gè)實(shí)例收奔。
3、保證了在高并發(fā)情況下滓玖,不會(huì)訪問到未初始化完成的對(duì)象造成系統(tǒng)異常問題坪哄。