java singleton 数据清楚_成都汇智动力-java singleton
原標(biāo)題:成都匯智動(dòng)力-java singleton
1.什么是單例模式?單例模式的應(yīng)用場(chǎng)景?
名稱:單例模式
英文名:Singleton
定義:java中單例模式是一種常見的設(shè)計(jì)模式,單例就是“一個(gè)對(duì)象,只實(shí)例化一次。”
分類:主要分為:“懶漢式”單例模式 ||“餓漢式”單例模式
具體分類定義:
(1)懶漢式:
//懶漢式單例類,在本類第一次調(diào)用的時(shí)候?qū)嵗约?/p>
publicclassLazyManSingleton {
//私有化構(gòu)造方法
private LazyManSingleton(){}
//定義空單例對(duì)象,不調(diào)用,則不實(shí)例
privatestaticLazyManSingleton single=null;
//靜態(tài)工廠方法
publicstaticLazyManSingleton getInstance()
{
if(single==null)
{ //當(dāng)被調(diào)用時(shí),實(shí)例化懶漢對(duì)象
single=new LazyManSingleton();}
returnsingle;
}
}
(2)餓漢式:
//餓漢式單例類,在類初始化時(shí),自行實(shí)例化
publicclassHungryManSingleton {
//私有化構(gòu)造方法
private HungryManSingleton (){}
//私有 “實(shí)例化后的” 化餓漢單例對(duì)象
privatestaticfinal HungryManSingleton single=new HungryManSingleton();
//靜態(tài)工廠方法
publicstatic HungryManSingletongetInstance()
{
//被調(diào)用時(shí)直接返回已經(jīng)準(zhǔn)備好的對(duì)象
returnsingle;
}
}
代碼理解:
首先看看代碼:無(wú)論是lazy還是hungry,他們的單例類都是相同步驟:
第一步:(壟斷)------私有化構(gòu)造器,這步有何作用呢?總所周知,私有化的東西(變量,方法,構(gòu)造器)只能被本類(A類)使用,其他類不能直接調(diào)用,就算是父子類也不行。所以私有化構(gòu)造器,就確保了其他類不能隨意調(diào)用A類的構(gòu)造方法,創(chuàng)建A類的實(shí)例對(duì)象了,這樣的話,想創(chuàng)建幾個(gè)A類對(duì)象就要看A類自己的心情了。A類想創(chuàng)建幾個(gè)就創(chuàng)建幾個(gè)。其他類因?yàn)檎{(diào)用不了A類的構(gòu)造器,所以永遠(yuǎn)都不能創(chuàng)建出一個(gè)A類對(duì)象。當(dāng)然,天無(wú)絕人之路,雖然其他類不能自己生產(chǎn)A類對(duì)象了,但是A類可以生產(chǎn)完“賣給”其他類呀,這就要看第二步,第三步了。
第二三步:(生產(chǎn)【盒子】【貨】,發(fā)貨)-------A類生產(chǎn),并傳遞A類對(duì)象的環(huán)節(jié)。這里也就是“懶漢”和“餓漢”的區(qū)別所在了,假設(shè)懶漢是A1類,這個(gè)A1很懶,做事拖沓,每次都不提前準(zhǔn)備一些貨(A1對(duì)象),以至于他的對(duì)象盒子是空的,只有在別的類來(lái)催的時(shí)候,才急急忙忙的在靜態(tài)工廠里生產(chǎn),生產(chǎn)完直接裝箱送貨。所以A1的靜態(tài)工廠,是既負(fù)責(zé)生產(chǎn),又負(fù)責(zé)發(fā)貨,苦啊,一條龍全包了
。 而“餓漢”A2類,那就不一樣,典型的高效外賣館啊,別人訂貨的瞬間就把盒飯打包好,然后瞬間傳遞到靜態(tài)工廠,A2的靜態(tài)工廠就只是一個(gè)送飯的作用了,不負(fù)責(zé)做飯。
單例模式的特點(diǎn):(1)單例類只能有一個(gè)實(shí)例
(2)單例類必須自己創(chuàng)建自己的唯一實(shí)例
(3)單例類必須給所有其他對(duì)象提供這一個(gè)實(shí)例
特點(diǎn)詳解:(1)單例模式為啥只有一個(gè)實(shí)例,為什么不多創(chuàng)建幾個(gè)實(shí)例?
答:單例模式,單例模式,顧名思義,只有一個(gè)實(shí)例,多好,多么的節(jié)約內(nèi)存,還不容易產(chǎn)生混淆。就一個(gè)實(shí)例還不好辨認(rèn)嗎?對(duì)象很安全。許多時(shí)候,整個(gè)系統(tǒng)只需要擁有一個(gè)全局對(duì)象,這樣的好處是,我們更容易協(xié)調(diào)系統(tǒng)整體的行為,這和秦始皇統(tǒng)一度量衡一個(gè)道理。專業(yè)點(diǎn)的解釋一下就是,比如某個(gè)服務(wù)器程序中,該服務(wù)器的配置信息存放在一個(gè)文件中,這些配置數(shù)據(jù)由一個(gè)單例對(duì)象統(tǒng)一讀取(咋讀取啊?),然后服務(wù)進(jìn)程中的其他對(duì)象再通過(guò)這個(gè)單例對(duì)象獲取這些配置信息。這種方式簡(jiǎn)化了復(fù)雜環(huán)境下的配置管理。叼!
(2)單例對(duì)象必須自己創(chuàng)建自己唯一的對(duì)象。
答:讀起來(lái)是不是很拗口?其實(shí)意思很簡(jiǎn)單,自己的對(duì)象自己建,別人辦事,我不放心,自己動(dòng)手,最合心意。單例類,他是干嘛的?為了啥,才被我們創(chuàng)建出來(lái)的?他的目的就是執(zhí)行統(tǒng)一大業(yè)的,統(tǒng)一度量衡,統(tǒng)一文字,統(tǒng)一車軌的,所以他就是標(biāo)準(zhǔn),他只能是唯一。如果楚國(guó)說(shuō):“秦國(guó),你的度量衡要按咱楚國(guó)的推廣”,齊國(guó)說(shuō):“秦國(guó),你的文字要按俺的來(lái)”,燕國(guó)說(shuō):“那車軌就按俺們那嘎達(dá)燕淫的”。你是秦國(guó),你咋辦?秦國(guó):“一群羊雜碎,統(tǒng)統(tǒng)按額們秦國(guó)滴標(biāo)準(zhǔn)來(lái)。”所以標(biāo)準(zhǔn)還得自己來(lái)造,交給別人一人一個(gè)樣。
(3)單例類必須給所有其他對(duì)象提供這一個(gè)實(shí)例
答:綜合上面那兩個(gè)特點(diǎn),最后一個(gè)就不用詳解了。你秦國(guó)統(tǒng)一文字,度量,車軌,法律干嘛呢,玩兒呢?肯定是推廣出去啊,讓別人也體驗(yàn)一下商鞅變法的封建主義的優(yōu)越性啊。
單例模式的應(yīng)用場(chǎng)景:
1.windows的任務(wù)管理器(ctrl+shift+esc),就是一個(gè)典型的單例模式,你試著打開兩個(gè)看看?逗你呢,他是單例模式,開不了兩個(gè)。
為什么不能打開兩個(gè)?(1)如果能彈出多個(gè)窗口,且這些窗口的內(nèi)容完全一致,全部是重復(fù)對(duì)象,這勢(shì)必會(huì)浪費(fèi)系統(tǒng)資源,任務(wù)管理器需要獲取系統(tǒng)運(yùn)行時(shí)的諸多信息,這些信息的獲取需要消耗一定的系統(tǒng)資源,包括cpu資源以及內(nèi)存資源,彈出多個(gè)內(nèi)容相同,操作相同的窗口,除了浪費(fèi)寶貴資源外,沒有任何好處。(2)如果彈出的多個(gè)窗口,內(nèi)容不一致,那不是你電腦中毒了,就是中毒了。
2.windows的回收站,在整個(gè)系統(tǒng)運(yùn)行過(guò)程中,回收站一直維護(hù)著僅有的一個(gè)實(shí)例。
3.網(wǎng)站的計(jì)數(shù)器,一般也是采用單例模式實(shí)現(xiàn),否則難以同步。
4.應(yīng)用程序的日志應(yīng)用,一般都用單例模式實(shí)現(xiàn),這一般是由于共享日志文件一直處于打開狀態(tài),因?yàn)橹荒苡幸粋€(gè)實(shí)例去操作,否則內(nèi)容不好追加。
5.Web應(yīng)用的配置對(duì)象的讀取,一般也應(yīng)用單例模式,這是由于配置文件是共享的資源。
6.數(shù)據(jù)庫(kù)連接池的設(shè)計(jì)一般也是采用單例模式,因?yàn)閿?shù)據(jù)庫(kù)連接是一種數(shù)據(jù)庫(kù)資源。數(shù)據(jù)庫(kù)軟件系統(tǒng)中使用數(shù)據(jù)庫(kù)連接池,主要是節(jié)省打開或者關(guān)閉數(shù)據(jù)庫(kù)所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因?yàn)椴捎脝卫J絹?lái)維護(hù),就可以大大降低這種損耗。
7.多線程的連接池的設(shè)計(jì)一般也是采用單里迷失,知識(shí)由于線程要方便對(duì)池中的線程進(jìn)行控制。
8.操作系統(tǒng)的文件系統(tǒng),也是大的單例模式實(shí)現(xiàn)的具體例子,一個(gè)操作系統(tǒng)只能有一個(gè)文件系統(tǒng)。
9.HttpApplication也是單例的典型應(yīng)用
總結(jié),單例模式的應(yīng)用場(chǎng)景一般發(fā)現(xiàn)在以下條件:
(1)資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能損耗,如上述的日志文件,應(yīng)用配置
(2)控制資源的情況下,方便資源之間的互相通訊,如線程池
懶漢模式與餓漢模式的優(yōu)缺點(diǎn)比較:
http://m.blog.csdn.net/article/details?id=26138355
1.時(shí)間和空間
懶漢式是典型的時(shí)間換空間,每次獲取實(shí)例,都會(huì)進(jìn)行判斷,如果已經(jīng)有了實(shí)例,就不實(shí)例化,如果沒有,則進(jìn)行實(shí)例化。當(dāng)一直沒人獲取懶漢實(shí)例,那么久節(jié)約了內(nèi)存空間。
餓漢式是典型的空間換時(shí)間,當(dāng)類被加載時(shí)就會(huì)創(chuàng)建實(shí)例,不管你用不用,先創(chuàng)建出來(lái),當(dāng)你需要獲取實(shí)例時(shí),就不需要判斷實(shí)例是否存在,直接給了就是。這就節(jié)約了時(shí)間。
2.線程安全
(1)從線程安全性上講,不加同步的懶漢式是線程不安全的,比如,有兩個(gè)線程,一個(gè)是線程A,一個(gè)是線程B,他們同時(shí)調(diào)用getInstance()方法,那就可能造成并發(fā)問(wèn)題,實(shí)例化出兩個(gè)實(shí)例,這就背離單例模式,懶漢式單例模式也會(huì)因此失效。
(2)餓漢式是線程安全,因?yàn)樘摂M機(jī)只會(huì)裝載一次,在裝載類的時(shí)候是不會(huì)發(fā)生并發(fā)的。
(3)如何實(shí)現(xiàn)懶漢式單例線程安全?
簡(jiǎn)單的實(shí)現(xiàn)方法:public static synchronized Singleton getInstance(){}
這種方法的缺點(diǎn)是降低了整個(gè)訪問(wèn)速度,而且每次都要判斷。
雙重檢查加鎖:
解釋:并不是每次進(jìn)入getInstance方法都需要同步,這里可以先不同步,進(jìn)入方法過(guò)后,先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊,這是第一重檢查。進(jìn)入同步塊后,再次檢查實(shí)例是否存在,如果不存在,就在同步的情況下創(chuàng)建一個(gè)實(shí)例,這是第二重檢查。這樣一來(lái),就只需要同步一次了,從而減少了多次在同步情況下進(jìn)行判斷所浪費(fèi)的時(shí)間。
雙重檢查加鎖機(jī)制的實(shí)現(xiàn)會(huì)使用一個(gè)關(guān)鍵字volatile,它的意思是:被volatile修飾的變量的值,將不會(huì)被本地線程緩存,所有對(duì)該變量的讀寫都是直接操作共享內(nèi)存,從而確保多個(gè)線程能正確的處理該變量。
看看代碼可能會(huì)更加清楚些。示例代碼如下:
publicclassSingleton{
privatevolatilestaticSingletoninstance=null;
privateSingleton(){
}
publicstaticSingletongetInstance(){
//先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊
if(instance==null){
//同步塊,線程安全地創(chuàng)建實(shí)例
synchronized(Singleton.class){
//再次檢查實(shí)例是否存在,如果不存在才真正地創(chuàng)建實(shí)例
if(instance==null){
instance=newSingleton();
}
}
}
returninstance;
}
責(zé)任編輯:
總結(jié)
以上是生活随笔為你收集整理的java singleton 数据清楚_成都汇智动力-java singleton的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大家说说简燚大理石瓷砖属于一线品牌瓷砖吗
- 下一篇: java7 arm_zynq7000系列