單例模式 Singleton Pattern

2022-03-09 20:41:17 字數 3010 閱讀 7892

單例模式-singleton pattern

何為單例模式,舉個大家都熟知的例子—— windows任務管理器,在windows的「工作列」的右 鍵彈出選單上多次點選「啟動任務管理器」,是不能同時開啟多個任務管理器視窗的。我們用**實現下:

假設任務管理器的類名為taskmanager,在 taskmanager類中包含了大量的成員方法,例如建構函式taskmanager(),顯示程序的方法

1

package

com.feimao.singleton.test;23

public

class

taskmanager 67

public

void

displayservices() 910

private taskmanager()

1213

public

static taskmanager tm = null;//

taskmanager中定義乙個靜態的taskmanager型別的私有成員變數,目的是為了讓外界可以訪問這個唯一例項

14public

static taskmanager getinstance()

18return

tm;19

}20 }

在類外我們無法直接建立新的taskmanager物件,但可以通過**taskmanager.getinstance()來 訪問例項物件,第一次呼叫getinstance()方法時將建立唯一例項,再次呼叫時將返回第一次創 建的例項,從而確保例項物件的唯一性。

單例模式(singleton pattern):確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項,這個類稱為單例類,它提供全域性訪問的方法。單例模式是一種物件建立型模式。

因程序需要,有時我們只需要某個類同時保留乙個物件,不希望有更多物件,此時,我們則應考慮單例模式的設計。

單例模式的特點:

1.單例模式只能有乙個例項。

2.單例類必須建立自己的唯一例項。

3.單例類必須向其他物件提供這一例項

在知道了什麼是單例模式後,我想你一定會想到靜態類,「既然只使用乙個物件,為何不乾脆使用靜態類?」,這裡我會將單例模式和靜態類進行乙個比較。

1.單例可以繼承和被繼承,方法可以被override,而靜態方法不可以。

2.靜態方法中產生的物件會在執行後被釋放,進而被gc清理,不會一直存在於記憶體中。

3.靜態類會在第一次執行時初始化,單例模式可以有其他的選擇,即可以延遲載入。

4.基於2, 3條,由於單例物件往往存在於dao層(例如sessionfactory),如果反覆的初始化和釋放,則會占用很多資源,而使用單例模式將其常駐於記憶體可以更加節約資源。

5.靜態方法有更高的訪問效率。

幾個關於靜態類的誤解:

誤解一:靜態方法常駐記憶體而例項方法不是。

實際上,特殊編寫的例項方法可以常駐記憶體,而靜態方法需要不斷初始化和釋放。

誤解二:靜態方法在堆(heap)上,例項方法在棧(stack)上。

實際上,都是載入到特殊的不可寫的**記憶體區域中。

靜態類和單例模式情景的選擇:

情景一:不需要維持任何狀態,僅僅用於全域性訪問,此時更適合使用靜態類。

情景二:需要維持一些特定的狀態,此時更適合使用單例模式。

1.懶漢模式(執行緒不安全)

1

package

com.feimao.a3.test;23

public

class

singletondemo 910

public

static

singletondemo getinstance()

14return

instance;15}

16 }

通過提供乙個靜態的物件instance,利用private許可權的構造方法和getinstance()方法來給予訪問者乙個單例。

缺點是,沒有考慮到執行緒安全,可能存在多個訪問者同時訪問,並同時構造了多個物件的問題。之所以叫做懶漢模式,主要是因為此種方法可以非常明顯的lazy loading。

針對懶漢模式執行緒不安全的問題,我們自然想到了,在getinstance()方法前加鎖,於是就有了第二種實現。

2.執行緒安全的懶漢模式(執行緒安全)

1

package

com.feimao.a3.test;23

public

class

singletondemo

8public

static

synchronized

singletondemo getinstance()

12return

instance;13}

14 }

3.餓漢模式(執行緒安全)

1

package

com.feimao.a3.test;23

public

class

singletondemo

8public

static

singletondemo getinstance()

11 }

直接在執行這個類的時候進行一次loading,之後直接訪問。顯然,這種方法沒有起到lazy loading的效果,考慮到前面提到的和靜態類的對比,這種方法只比靜態類多了乙個記憶體常駐而已。

4.靜態類內部載入(執行緒安全)

1

package

com.feimao.a3.test;23

public

class

singletondemo 78

private

singletondemo()

1112

public

static

singletondemo getinstance()

15 }

單例模式 單例模式

餓漢式 急切例項化 public class eagersingleton 2.宣告靜態成員變數並賦初始值 類初始化的時候靜態變數就被載入,因此叫做餓漢式 public static eagersingleton eagersingleton new eagersingleton 3.對外暴露公共的...

單例 單例模式

簡單的實現乙個單例 instancetype sharedinstance return instance 真正的單例模式 myclass sharedinstance return instance id allocwithzone nszone zone return nil id copywi...

單例模式 懶漢式單例模式

單例模式有餓漢時模式和懶漢式 單例模式也就是說同一類只返回乙個物件供外部類使用 懶漢式即延遲初始化單例。在多執行緒環境下,簡單的懶漢式會有執行緒安全。懶漢式單例模式解決線性安全問題如下 1 使用雙重檢查鎖機制解決執行緒安全問題。2 單例模式還有更好的解決方案,即使用靜態類方式。懶漢式單例模式典型 p...