23種設計模式(單例模式)

2021-10-13 03:04:07 字數 1906 閱讀 6916

(願歲月清淨)

單例模式: 確保乙個類最多只有乙個例項,提供乙個全域性訪問點

注意:

單例模式可以分為兩種:

1.預載入(餓漢式)

預先載入。還沒有使用該單例物件,但是該單例物件就已被載入到記憶體。

public

class

hungry

;public

static hungry getinstance()

}

若沒有使用該單例物件,該物件就被載入到了記憶體,會造成記憶體的浪費。

2.懶載入(懶漢式)

為了避免記憶體的浪費,可以採用懶載入,即用到該單例物件的時候再建立。

public

class

lazy

;public

static lazy getinstance()

return instance;

}}

3. 單例模式和執行緒安全

餓漢式只有一條語句return instance,可以保證執行緒安全。但會造成記憶體的浪費。

懶漢式不浪費記憶體,但是無法保證執行緒的安全。首先,if判斷以及其記憶體執行**是非原子性的。其次,new singleton()無法保證執行的順序性。不滿足原子性或者順序性,執行緒肯定是不安全的,不再贅述。

為什麼new singleton()無法保證順序性。建立乙個物件分三步:

memory=

allocate()

;//1:初始化記憶體空間

ctorinstance

(memory)

;//2:初始化物件

instance=

memory()

;//3:設定instance指向剛分配的記憶體位址

jvm為了提高程式執行效能,會對沒有依賴關係的**進行重排序,上面2和3行**可能被重新排序。我們用兩個執行緒來說明執行緒是不安全的。執行緒a和執行緒b都建立物件。其中,a2和a3的重排序,將導致執行緒b在b1處判斷出instance不為空,執行緒b接下來將訪問instance引用的物件。此時,執行緒b將會訪問到乙個還未初始化的物件(執行緒不安全)。

4. 懶漢式的執行緒安全解決方法

使用synchronized關鍵字。synchronized載入getinstace()函式上確實保證了執行緒的安全。

注意:若要經常的呼叫getinstance()方法,不管有沒有初始化例項,都會喚醒和阻塞執行緒。為了避免執行緒的上下文切換消耗大量時間,如果物件已經例項化了,我們沒有必要再使用synchronized加鎖,直接返回物件。

public

class

lazy

;public

static

synchronized lazy getinstance()

return instance;

}}

把sychronized加在if(instance==null)判斷語句裡面,保證instance未例項化的時候才加鎖

public

class

lazy

;public

static

synchronized lazy getinstance()

}}return instance;

}}

new乙個物件的**是無法保證順序性的,需要使用關鍵字volatile保證物件例項化過程的順序性。

public

class

lazy

;public

static

synchronized lazy getinstance()

}}return instance;

}}

即保證了懶漢式的執行緒安全。

23種設計模式 單例模式

某些情況,如 執行緒池,乙個專案中匯流排程數量以及生命週期,可能需要統一控制 如果執行緒池自身可建立多個例項,那麼就無法統一控制,此時,只要能控制線程池物件的數量為乙個,那麼就可以實現統一控制的目標 注意 現實中真正使用純的單例模式並不多 如 spring bean 通過配置來決定是否使用單例 執行...

單例模式(23種設計模式)

單例模式 餓漢模式 class singletondemo public static singletondemo gets 懶漢模式 class singletondemo1 public static singletondemo1 gets return instance 單例模式,懶漢式,執行...

23種設計模式 單例模式

單例模式需要保證,構造方法一定是私有化的,並且類的全域性變數必須是靜態的,私有的 這樣才能有唯一的例項化途徑 錯誤 一 public class singleton public static singleton getinstance 上述方法,並沒有把類變數singleton設定為靜態的,這樣,...