設計模式之單例模式

2021-08-09 11:35:55 字數 3043 閱讀 3355

單例模式也叫做單肩模式,也是一種建立型模式,是我們日常開發中最常使用的一種設計模式,經常被用來封裝一些工具類,例如資料庫連線等。

單例模式的定義:

單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項。即乙個類只有乙個物件例項

單例模式分為以下幾種:

①餓漢單例模式

②懶漢單例模式

③iodh單例模式

④列舉單例模式

下面我們一一的進行介紹:

1.首先是餓漢單例模式,顧名思義「餓漢」,代表急著「吃飯」(這裡的飯應該是指的例項物件),所以很早就建立出來。不多說,上**:

package singleton;

public

class hungrysingletonp

public

static hungrysingletonp getinstance()

}

這段**很形象的體現了餓漢模式。

2.懶漢模式,同樣什麼叫做懶漢模式?乙個懶惰的人,只有去吃飯的時候才會去刷碗(昨天用過的髒碗),即:只有當用到物件的時候才去建立物件,來上**:

package singleton;

public

class lasysingletonv1

public

static lasysingletonv1 getinstance()else

return instance;

}}

上面的這段**是懶漢模式,當我們不需要例項的時候,它不會建立例項,只有需要例項的時候,才會建立,節省空間。

但是,我們不推薦使用,因為我們原來的設計理念是:當需要的時候(並且instance為空)建立例項,當已經建立過後,如果還需要例項,則判斷instance是否為空,因為前邊已經建立過了,不為空,所以直接返回之前已經建立的例項。

以上的想法是很好的,但是它是執行緒不安全的。因為:當有多個執行緒同時呼叫這個方法時,因為同時判斷例項為空,所以會建立很多個例項,這不符合單例模式的設計理念(乙個類只有乙個例項物件)。

所以我們需要對它進行改進,因為它會非同步建立多個例項,多以我們很容易就能想到,在getinstance方法之前加上synchronized進行同步:

package singleton;

public

class

lasysingletonv2

public

synchronized lasysingletonv2 getinstance()else

return instance;

}}

上面這樣,就不會建立多個例項物件符合單例模式的概念。

但是上面這樣的設計使得我們每次需要目標例項的時候都要排隊等待,假設有很多執行緒都在呼叫這個getinstance方法,那麼就會陷入很長時間的等待,大大降低的程式的效率。

所以我們還要對程式進行一定的修改,如果我們建立乙個

package singleton;

public

class

lasysingletonv3

public lasysingletonv3 getinstance()}}

return instance;

}}

以上的方法是懶漢模式的完整版本,我們來仔細分析一下:

當有多個執行緒第一次呼叫這個方法的時候,都滿足instance為空,來到下一步,先獲得鎖的執行緒進入下一步繼續判斷是否為空,為空,然後建立例項返回例項。

沒有獲得鎖的執行緒一直等待到獲得鎖的執行緒釋放鎖,當在等待的執行緒獲得鎖的時候進入下一步,還要進行判斷instance是否為空,但是這個時候instance已經不為空了,因為前面的執行緒已經建立了例項,所以返回已經建立好的例項。

以上是第一批呼叫getinstance方法的執行緒,當後續的執行緒呼叫這個方法的時候就不用進行鎖的獲取了和釋放了,因為第一步已經判斷instance不為空,直接返回instance例項。

有人肯定會疑問為什麼要進行兩次的判斷呢?

如果我們只執行一次判斷,分為兩種:

一種是在synchronized關鍵字之前進行判斷,當第一批執行緒同時呼叫getinstance方法的時候判斷都會為空,然後第乙個獲得鎖的進行建立例項,然後下乙個執行緒獲得鎖後也會建立例項,這就建立多個例項物件了。

另一種是在synchronized關鍵字之後進行判斷,這樣就和第二種版本比較像了,每次呼叫都需要等待,會大大降低程式的效率。

結合和吸取上面的兩種方法的優點和缺點,我們既在synchronized之前進行判斷(減少每次都要獲得鎖等待的時間),又在synchronized之後進行判斷(防止建立多個例項物件)。

以上的分析和**就是懶漢模式的最終分析和方法。

下面就是我們的第三種單例模式:iodh單例模式。

iodh是initialization demand holder 英文的縮寫,簡單來說就是在單例類中增加乙個靜態內部類,在該內部類中建立單例類的例項(關於內部類)。

將乙個靜態內部類放在單例類中,並在這個內部類中建立例項,這樣單例類在被載入的時候就不會建立例項了。

package singleton;

public

class singletoniodh

private

static

class innerclass

public

static singletoniodh getinstance()

}

我們上面只說到,當這個類被載入過後不被例項化,但是如何避免在呼叫的時候多個執行緒同時呼叫產生多個例項呢?

我們知道static的一些特性,乙個類的static欄位或者static{}(靜態塊)是由jvm進行初始化的,jvm在進行初始化的時候已經進行了同步處理,所以我們不必擔心會建立多個例項。

最後一種就是列舉單例模式

因為列舉bz還沒學習到,以後再進行補充。

設計模式之單例模式

前一段時間買了一本秦小波寫的 設計模式之禪 網上對這書的評價很高。現在還沒有看很多,但是有些地方頗有感觸,也並不是所有的地方都能看懂,但是會慢慢研究的。自己對於設計模式的感覺就是乙個字 牛!感覺會23種設計模式並且會熟練運用的人,真的就是大師級的牛人了,設計模式是乙個專案主管或者架構師一定要會的東西...

設計模式之單例模式

package com.xie.singleton public class singleton 提供乙個共有的靜態的入口方法 public static singleton getinstance 懶漢式 延遲載入 提供乙個私有的靜態的成員變數,但不做初始化 private static sing...

設計模式之 單例模式

單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式 單件模式 使用方法返回唯一的例項 public class singleton private static singleton instance public static singleton geti...