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