【移動應(yīng)用開發(fā)技術(shù)】如何解析Android Java語言中單例這種設(shè)計模式_第1頁
【移動應(yīng)用開發(fā)技術(shù)】如何解析Android Java語言中單例這種設(shè)計模式_第2頁
【移動應(yīng)用開發(fā)技術(shù)】如何解析Android Java語言中單例這種設(shè)計模式_第3頁
【移動應(yīng)用開發(fā)技術(shù)】如何解析Android Java語言中單例這種設(shè)計模式_第4頁
免費預(yù)覽已結(jié)束,剩余1頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】如何解析AndroidJava語言中單例這種設(shè)計模式

本篇文章為大家展示了如何解析AndroidJava語言中單例這種設(shè)計模式,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。概念單例模式,又稱單件模式或者單子模式,指的是一個類只有一個實例,并且提供一個全局訪問點。實現(xiàn)思路在單例的類中設(shè)置一個private靜態(tài)變量sInstance,sInstance類型為當(dāng)前類,用來持有單例***的實例。將(無參數(shù))構(gòu)造器設(shè)置為private,避免外部使用new構(gòu)造多個實例。提供一個public的靜態(tài)方法,如getInstance,用來返回該類的***實例sInstance。其中上面的單例的實例可以有以下幾種創(chuàng)建形式,每一種實現(xiàn)都需要保證實例的***性。餓漢式餓漢式指的是單例的實例在類裝載時進(jìn)行創(chuàng)建。如果單例類的構(gòu)造方法中沒有包含過多的操作處理,餓漢式其實是可以接受的。餓漢式的常見代碼如下,當(dāng)SingleInstance類加載時會執(zhí)行private

static

SingleInstance

sInstance

=

new

SingleInstance();初始化了***的實例,然后getInstance()直接返回sInstance即可。public

class

SingleInstance

{

private

static

SingleInstance

sInstance

=

new

SingleInstance();

private

SingleInstance()

{

}

public

static

SingleInstance

getInstance()

{

return

sInstance;

}

}餓漢式的問題如果構(gòu)造方法中存在過多的處理,會導(dǎo)致加載這個類時比較慢,可能引起性能問題。如果使用餓漢式的話,只進(jìn)行了類的裝載,并沒有實質(zhì)的調(diào)用,會造成資源的浪費。懶漢式懶漢式指的是單例實例在***次使用時進(jìn)行創(chuàng)建。這種情況下避免了上面餓漢式可能遇到的問題。但是考慮到多線程的并發(fā)操作,我們不能簡簡單單得像下面代碼實現(xiàn)。public

class

SingleInstance

{

private

static

SingleInstance

sInstance;

private

SingleInstance()

{

}

public

static

SingleInstance

getInstance()

{

if

(null

==

sInstance)

{

sInstance

=

new

SingleInstance();

}

return

sInstance;

}

}上述的代碼在多個線程密集調(diào)用getInstance時,存在創(chuàng)建多個實例的可能。比如線程A進(jìn)入null==sInstance這段代碼塊,而在A線程未創(chuàng)建完成實例時,如果線程B也進(jìn)入了該代碼塊,必然會造成兩個實例的產(chǎn)生。synchronized修飾方法使用synchrnozed修飾getInstance方法可能是最簡單的一個保證多線程保證單例***性的方法。synchronized修飾的方法后,當(dāng)某個線程進(jìn)入調(diào)用這個方法,該線程只有當(dāng)其他線程離開當(dāng)前方法后才會進(jìn)入該方法。所以可以保證getInstance在任何時候只有一個線程進(jìn)入。public

class

SingleInstance

{

private

static

SingleInstance

sInstance;

private

SingleInstance()

{

}

public

static

synchronized

SingleInstance

getInstance()

{

if

(null

==

sInstance)

{

sInstance

=

new

SingleInstance();

}

return

sInstance;

}

}但是使用synchronized修飾getInstance方法后必然會導(dǎo)致性能下降,而且getInstance是一個被頻繁調(diào)用的方法。雖然這種方法能解決問題,但是不推薦。雙重檢查加鎖使用雙重檢查加鎖,首先進(jìn)入該方法時進(jìn)行null==sInstance檢查,如果***次檢查通過,即沒有實例創(chuàng)建,則進(jìn)入synchronized控制的同步塊,并再次檢查實例是否創(chuàng)建,如果仍未創(chuàng)建,則創(chuàng)建該實例。雙重檢查加鎖保證了多線程下只創(chuàng)建一個實例,并且加鎖代碼塊只在實例創(chuàng)建的之前進(jìn)行同步。如果實例已經(jīng)創(chuàng)建后,進(jìn)入該方法,則不會執(zhí)行到同步塊的代碼。public

class

SingleInstance

{

private

static

volatile

SingleInstance

sInstance;

private

SingleInstance()

{

}

public

static

SingleInstance

getInstance()

{

if

(null

==

sInstance)

{

synchronized

(SingleInstance.class)

{

if

(null

==

sInstance)

{

sInstance

=

new

SingleInstance();

}

}

}

return

sInstance;

}

}volatile是什么Volatile是輕量級的synchronized,它在多處理器開發(fā)中保證了共享變量的“可見性”??梢娦缘囊馑际钱?dāng)一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。使用volatile修飾sInstance變量之后,可以確保多個線程之間正確處理sInstance變量。關(guān)于volatile,可以訪問深入分析Volatile的實現(xiàn)原理了解更多。利用static機制在Java中,類的靜態(tài)初始化會在類被加載時觸發(fā),我們利用這個原理,可以實現(xiàn)利用這一特性,結(jié)合內(nèi)部類,可以實現(xiàn)如下的代碼,進(jìn)行懶漢式創(chuàng)建實例。public

class

SingleInstance

{

private

SingleInstance()

{

}

public

static

SingleInstance

getInstance()

{

return

SingleInstanceHolder.sInstance;

}

private

static

class

SingleInstanceHolder

{

private

static

SingleInstance

sInstance

=

new

SingleInstance();

}

}關(guān)于這種機制,可以具體了解雙重檢查鎖定與延遲初始化好奇問題真的只有一個對象么其實,單例模式并不能保證實例的***性,只要我們想辦法的話,還是可以打破這種***性的。以下幾種方法都能實現(xiàn)。使用反射,雖然構(gòu)造器為非公開,但是在反射面前就不起作用了。如果單例的類實現(xiàn)了cloneable,那么還是可以拷貝出多個實例的。Java中的對象序列化也有可能導(dǎo)致創(chuàng)建多個實例。避免使用readObject方法。使用多個類加載器加載單例類,也會導(dǎo)致創(chuàng)建多個實例并存的問題。單例可以繼承么單例類能否被繼承需要分情況而定??梢岳^承的情況當(dāng)子類是父類單例類的內(nèi)部類時,繼承是可以的。public

class

BaseSingleton

{

private

static

volatile

BaseSingleton

sInstance;

private

BaseSingleton()

{

}

public

static

BaseSingleton

getInstance()

{

if

(null

==

sInstance)

{

synchronized(BaseSingleton.class)

{

if

(null

==

sInstance)

{

sInstance

=

new

BaseSingleton();

}

}

}

return

sInstance;

}

public

static

class

MySingleton

extends

BaseSingleton

{

}

}但是上面僅僅是編譯和執(zhí)行上允許的,但是繼承單例沒有實際的意義,反而會變得更加事倍功半,其代價要大于新寫一個單例類。感興趣的童鞋可以嘗試折騰一下。不可以繼承的情況如果子類為單獨的類,非單例類的內(nèi)部類的話,那么在編譯時就會出錯ImplicitsuperconstructorBaseSingleton()isnotvisiblefordefaultconstructor.Mustdefineanexplicitconstructor,主要原因是單例類的構(gòu)造器是private,解決方法是講構(gòu)造器設(shè)置為可見,但是這樣

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論