單例模式的八種寫法

2022-02-20 01:46:56 字數 3138 閱讀 8621

1、餓漢式(靜態常量)(執行緒安全)

public

class

singleton

public

static

singleton getinstance()

}

優點:這種寫法比較簡單,就是在類裝載的時候就完成例項化。避免了執行緒同步問題。

缺點:在類裝載的時候就完成例項化,沒有達到lazy loading的效果。如果從始至終從未使用過這個例項,則會造成記憶體的浪費。

2、餓漢式(靜態**塊)(執行緒安全)

public

class

singleton

private

singleton() {}

public

static

singleton getinstance()

}

這種方式和上面的方式類似,只不過將類例項化的過程放在了靜態**塊中,也是在類裝載的時候,就執行靜態**塊中的**,初始化類的例項。

3、懶漢式(執行緒不安全)

public

class

singleton

public

static

singleton getinstance()

return

singleton;

}}

4、懶漢式(執行緒安全,同步方法)

public

class

singleton

public

static

synchronized

singleton getinstance()

return

singleton;

}}

說明:synchronized

將getinstance() 進行了執行緒同步,執行效率低下

5、懶漢式(執行緒不安全,同步**塊)

public

class

singleton

public

static

singleton getinstance()

}return

singleton;

}}

說明:當多個執行緒同時到達且均執行了if (singleton == null)判斷語句時,便會建立多個例項。

6、雙重檢查(執行緒不安全)

public

class

singleton

public

static

singleton getinstance() }}

return

singleton;

}}

分析:new編譯後的偽**表示:

alloc = allocat(); //

分配記憶體位址 #1

constructor(alloc); //

執行建構函式,建立物件 #2

singleton = alloc; //

引用指向 #3

指令重排後表示

alloc = allocat(); //

分配記憶體位址 #1

singleton = alloc ; //

引用指向 #3 當第乙個執行緒執行到這裡時,由於執行緒排程,並未執行下面的物件建立指令,此時恰好有其他執行緒呼叫getinstance(),而singleton引用已不為null,就會返回沒有物件的位址引用,使用時引發物件不存在異常

constructor(alloc ); //

執行建構函式,建立物件 #2

7、雙重檢查+volatile (執行緒安全)

public

class

singleton

public

static

singleton getinstance() }}

return

singleton;

}}

說明:volatile 關鍵字阻止了使用singleton**行前後的指令重排

優點:執行緒安全;延遲載入;效率較高。

8、靜態內部類(執行緒安全)

public

class

singleton

private

static

class

singletoninstance

public

static

singleton getinstance()

}

說明:這種方式跟餓漢式方式採用的機制類似,但又有不同。兩者都是採用了類裝載的機制來保證初始化例項時只有乙個執行緒。不同的地方在餓漢式方式是只要singleton類被裝載就會例項化,沒有lazy-loading的作用,而靜態內部類方式在singleton類被裝載時並不會立即例項化,而是在需要例項化時,呼叫getinstance方法,才會裝載singletoninstance類,從而完成singleton的例項化。

類的靜態屬性只會在第一次載入類的時候初始化,所以在這裡,jvm幫助我們保證了執行緒的安全性,在類進行初始化時,別的執行緒是無法進入的。

優點:避免了執行緒不安全,延遲載入,效率高。

9、列舉(執行緒安全)

public

enum

singleton

}

說明:借助jdk1.5中新增的列舉來實現單例模式。不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件。

優點:系統記憶體中該類只存在乙個物件,節省了系統資源,對於一些需要頻繁建立銷毀的物件,使用單例模式可以提高系統效能。

列舉單例示例:獲取資料庫連線。

public

enum

datasourceenum     

public

dbconnection getconnection()

}  

public

class

dbconnection {}

public

class

main

}

單例模式的八種寫法

單例模式是最常用到的設計模式之一,熟悉設計模式的朋友對單例模式都不會陌生。一般介紹單例模式的書籍都會提到餓漢式和懶漢式這兩種實現方式。但是除了這兩種方式,本文還會介紹其他幾種實現單例的方式,讓我們來一起看看吧。單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許乙個例項存在。許多時候整個系...

單例模式的八種寫法

單例模式是最常用到的設計模式之一,熟悉設計模式的朋友對單例模式都不會陌生。一般介紹單例模式的書籍都會提到 餓漢式 和 懶漢式 這兩種實現方式。但是除了這兩種方式,本文還會介紹其他幾種實現單例的方式,讓我們來一起看看吧。簡介單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許乙個例項存在。許...

單例模式的八種寫法

介紹 單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許乙個例項存在。許多時候整個系統只需要擁有乙個的全域性物件,這樣有利於我們協調系統整體的行為。比如在某個伺服器程式中,該伺服器的配置資訊存放在乙個檔案中,這些配置資料由乙個單例物件統一讀取,然後服務程序中的其他物件再通過這個單例物件獲...