學習筆記 設計模式 4 單件模式

2021-07-27 02:39:26 字數 1811 閱讀 9464

在乙個大型系統中,不可避免的會出現只能存在乙個的類,比如執行緒池,對話方塊,配置設定等等,如果參與開發系統的人不止乙個(這是很常見的場景),就無法保證不會有兩個人同時在自己的**裡例項化了這個只能存在乙個的類。

下面介紹的單件模式(單例模式)就可以在根源(只能存在乙個的類)上避免出現上面的問題。

首先介紹一下單件模式的定義:

確保乙個類只有乙個例項,並提供乙個全域性訪問點。

單件模式有很多種實現的形式,下面從最簡單的實現說起。

如果要讓別人不隨便例項化自己,很明顯需要把自己的構造器宣告為私有的,然後提供給外部的是乙個經過處理的「構造方法」。

下面是經典單件模式的實現**:

public

class

singleton

public

static singleton getinstance()

return singleton;

}}

當別的類需要使用singleton類時,只需要呼叫getinstance()方法,就可以獲得乙個singleton類,而只有在第乙個呼叫者會讓這個類例項化,之後的呼叫者都是呼叫的之前例項化過的類。

通過這種方法,就可以「保證」singleton在使用的時候只會存在乙個例項。

但是,這是在沒有考慮多執行緒的情況下才能好用的方法,如果有多個執行緒同時呼叫了getinstance()方法,可能就會產生多個singleton類,這樣就會出現單件類不單件的情況。

下面的幾種模式都是為了應對這種情況而產生的:

public

class

singleton

public

static

synchronized singleton getinstance()

return singleton;

}

既然多執行緒在同時呼叫getinstance()方法時,可能會出現同時判斷singleton == null的情況,那我們只需要加上synchronized關鍵字,讓這個方法在多執行緒的過程中只能一次執行乙個。

但是這樣做會導致乙個新的問題:效率變低。很明顯的是,我們只需要在第一次呼叫的時候保證沒有兩個執行緒同時進入這個方法就可以保證正常工作,而加上synchronized後,每次呼叫都會要同步等待,這樣會很浪費時間!

如果對singleton的判空會導致多執行緒的問題,那我們乾脆直接在程式啟動的時候就例項化這個物件!

public

class

singleton

public

static

synchronized singleton getinstance()

通過這個方法,我們在jvm載入這個類的時候對這個類進行例項化,那麼我們就不需要關心多執行緒衝突的問題了。但是這樣的操作會導致程式的啟動的時候負擔太重,如果有多個這樣的單例或者有沒有呼叫過的單例,這樣的方法就會浪費空間和時間。

使用volatile關鍵字,確保變數被處理的時候,多執行緒可以正確的工作。

「雙重檢查加鎖」方法實現如下:

public

class

singleton

public

static singleton getinstance()}}

return singleton;

}}

第乙個判斷為真後,會再次進入乙個同步的判斷,這樣即使多個執行緒同時進入了第乙個判斷,也會同步地進行下乙個判斷,如果為真則會進行物件的例項化。

設計模式學習筆記之 單件模式

單件模式的關鍵是確保只有乙個例項。1 經典單件模式 又稱懶漢模式 public class singleton public static singleton getinstance return uniquesingleton 特點 1 構造方法是私有的,僅在singleton類內部才可以被呼叫 ...

設計模式學習筆記(十四 單件模式)

保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。這就是單件模式的定義。在某些情況下,我們可能需要某個類只能建立乙個物件,即不讓使用者用該類例項化出多於兩個的例項。例如,在乙個公文管理系統中,公文類的例項 公文檔案 需要將公章類的例項作為自己的乙個成員,以表明自己是乙個有效的公文檔案,那麼系統...

GOF 設計模式 單件模式 筆記

意圖 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性終點。結構 在以下情況使用它 對於某些類來說,只有乙個例項是很重要的,可以讓類自身儲存它的唯一例項,並這個類隱藏他的建立介面,並提供乙個訪問例項的介面。還可以使用惰性初始化,或者用乙個靜態內部類儲存。apublic class a public ...