設(shè)計(jì)系統(tǒng)時(shí),通常希望控制對(duì)象的用法,防止用戶(hù)復(fù)制對(duì)象或建立新實(shí)例。例如,你可以使用它創(chuàng)建一個(gè)連接池,每次程序需要往數(shù)據(jù)庫(kù)中寫(xiě)入內(nèi)容時(shí)才創(chuàng)建一個(gè)新連接的做法并不明智;相反,一個(gè)或一組已經(jīng)在池中的連接就可以使用Singleton模式實(shí)例化。
Singleton模式常常和工廠(chǎng)方法模式一同使用,創(chuàng)建一個(gè)系統(tǒng)級(jí)資源,使用這個(gè)資源的代碼并不知道它的特殊類(lèi)型。抽象窗口工具包(AWT)就是組合使用這兩個(gè)模式的典型例子。在GUI應(yīng)用程序中,對(duì)每個(gè)應(yīng)用程序?qū)嵗阋话阒恍枰粋€(gè)圖形元素的實(shí)例,如打印(Print)對(duì)話(huà)框或OK按鈕。 3、類(lèi)圖 4、單例模式的運(yùn)行機(jī)制 Singleton是一個(gè)無(wú)法實(shí)例化的對(duì)象。這種設(shè)計(jì)模式暗示,在任何時(shí)候,只能由JVM創(chuàng)建一個(gè)Singleton(對(duì)象)實(shí)例。如果實(shí)例不存在,你通過(guò)創(chuàng)建類(lèi)的新實(shí)例的方法建立一個(gè)類(lèi)來(lái)執(zhí)行這個(gè)模式;如果存在類(lèi)的一個(gè)實(shí)例,就只會(huì)返回那個(gè)對(duì)象的一個(gè)引用。 下面看看單例模式的幾種實(shí)現(xiàn)方式: 方式1:
方式2:
方式2就是我們說(shuō)的:滯后初始化(Lazy Initialization)。為什么會(huì)有滯后初始化這種實(shí)現(xiàn)方式出現(xiàn)呢?我們可用看到在第一種實(shí)現(xiàn)方式中無(wú)法向單例模式的構(gòu)造方法傳遞參數(shù),而使用滯后初始化的方式,我們可用在調(diào)用getInstance()方法的時(shí)候向方法中傳遞參數(shù)。
凡事有好處必然有壞處,滯后初始化的一個(gè)弊病就是在多線(xiàn)程或分布式的環(huán)境下有可能出現(xiàn)混亂:
“有時(shí)在某些情況下,使用Singleton并不能達(dá)到Singleton的目的,如有多個(gè)Singleton對(duì)象同時(shí)被不同的類(lèi)裝入器裝載;在EJB這樣的分布式系統(tǒng)中使用也要注意這種情況,因?yàn)镋JB是跨服務(wù)器,跨JVM的。” --摘自www.jdon.com-《GoF 23種設(shè)計(jì)模式解析》
“在多線(xiàn)程環(huán)境下,我們無(wú)法保證一個(gè)方法能夠持續(xù)運(yùn)行到結(jié)束,其他線(xiàn)程的方法才開(kāi)始運(yùn)行。因而可能存在這樣一種情形:兩個(gè)線(xiàn)程幾乎同時(shí)嘗試初始化單例類(lèi)。假設(shè)第一個(gè)方法發(fā)現(xiàn)單例為空,而第二個(gè)方法在此刻開(kāi)始運(yùn)行,它也會(huì)發(fā)現(xiàn)該單例為空。接下來(lái),這兩個(gè)方法都將對(duì)該單例進(jìn)行初始化。” --摘自《Java設(shè)計(jì)模式》 那么在多線(xiàn)程的環(huán)境下我們?cè)趺锤踩氖褂脝卫J侥兀?br /> 方式3: 《Java并發(fā)編程》一書(shū)建議使用屬于當(dāng)前類(lèi)的鎖進(jìn)行同步,代碼如下:
在第一個(gè)線(xiàn)程開(kāi)始滯后初始化的時(shí)候,如果有另一線(xiàn)程也準(zhǔn)備開(kāi)始初始化,這時(shí)候,第二個(gè)線(xiàn)程將停止執(zhí)行,等待獲取對(duì)象classLock的鎖。當(dāng)?shù)诙€(gè)線(xiàn)程獲取這個(gè)鎖并開(kāi)始執(zhí)行初始化的時(shí)候,它會(huì)發(fā)現(xiàn)該單例已不再為空(因?yàn)橹淮嬖谠擃?lèi)的唯有實(shí)例,我們可以使用單個(gè)靜態(tài)鎖)。 或者:
另一個(gè)解決辦法是在getInstance()方法聲明中添加synchronized關(guān)鍵字:
posted on 2008-05-28 16:57 云淡風(fēng)清 閱讀(741) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): Design Patterns
Powered by: BlogJava Copyright © 云淡風(fēng)清