1. 程式人生 > >Double Check形式的單例模式

Double Check形式的單例模式

這兩天在看開源專案時,發現Event Bus和Universalimageloader中寫單例模式都是Double Check的形式。平時總是看到各種各樣的單例模式,如,餓漢式,懶漢式等等。其中大多存在問題。今天記錄一種比較優秀的單例模式的寫法------Double Check。以後我準備就用這種方法了。(雖然還有其他優秀的方式,比如內部靜態類,列舉)

先上程式碼:

public class ImageLoader {

	private volatile static ImageLoader instance;

	// Returns singleton class instance
	public static ImageLoader getInstance() {
		if (instance == null) {
			synchronized (ImageLoader.class) {
				if (instance == null) {
					instance = new ImageLoader();
				}
			}
		}
		return instance;
	}
}

這是EventBus中的程式碼。其中兩次檢查是否instance == null,第一個是為了避免每次都加鎖,畢竟這有一定的開銷。第二個是為了避免同步問題,比如十個執行緒同時呼叫getInstance()方法,都執行了第一步檢查instance == null,並且其中一個執行緒成功獲得了鎖(執行了synchronized語句),接下來如果沒有再一次判斷instance == null,則十個執行緒將生成10物件,這違背了單例的初衷。

上述程式碼除了有兩次檢查instance == null,另一個特點是變數instance的型別宣告中添加了volatile,因為像下面這種建立物件的語句並不是原子操作,volatile可以使其成為原子操作,避免同步問題。

instance = new ImageLoader();

雖說部分JVM沒有完全volatile,但是目前主流的JVM貌似已經都支援了,所以這個問題一般可以忽略。

參考:

相關推薦

通過double-check解決模式效率低的問題

    單例模式的應用場景是在一個專案系統執行的過程中某一個類只被建立一次,也就是說只允許一個該類的一個物件存在。其實如果想實現這種目的有很多方法,這裡我之所以提及是因為我之前在使用單例模式的時候沒有注意到我的單例模式程式碼還有提高效率的空間,接下來將把我之前實現單例模式的程

Double Check形式模式

這兩天在看開源專案時,發現Event Bus和Universalimageloader中寫單例模式都是Double Check的形式。平時總是看到各種各樣的單例模式,如,餓漢式,懶漢式等等。其中大多存在問題。今天記錄一種比較優秀的單例模式的寫法------Double Ch

設計模式模式二(懶漢式double check

上一篇文章中的懶漢式單例模式採用同步方法保證了執行緒安全,但是開銷很大,每次執行該方法都會檢查鎖。下面採用double check的方式進行改寫,下面這種實現看似可行,實則有缺陷,具體缺陷在後文分析: 注意上面第二幅圖中對lazyDoubleCheckSingl

模式的8種寫法及其分析 (推薦:double check,內部類,列舉的寫法)

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

模式中的Double check lock

Double check lock package test; public class Singleton { public static Singleton singleton; private Singleton(){ }

Java 模式中使用雙重檢查(Double-Check

在 Effecitve Java 一書的第 48 條中提到了雙重檢查模式,並指出這種模式在 Java 中通常並不適用。該模式的結構如下所示: public Resource getResource() {     if (resource == null)

Java使用double check(雙重檢查)實現模式的一個小細節

public class Singleton { private static Singleton singleton; private Singleton() { } public static Singleton getIn

設計模式模式介紹及8種寫法(餓漢式、懶漢式、Double-Check、靜態內部類、列舉)

# 一、餓漢式(靜態常量) 這種餓漢式的單例模式構造的步驟如下: 1. 構造器私有化;(防止用new來得到物件例項) 2. 類的內部建立物件;(因為1,所以2) 3. 向外暴露一個靜態的公共方法;(getInstance) 示例: ```java class Singleton{ //

模式“雙重檢查鎖定Double-Checked Locking”執行緒安全問題

幾篇合集。 1 單例模式“雙重檢查鎖定Double-Checked Locking”執行緒安全問題 https://blog.csdn.net/wabiaozia/article/details/84723899 2 主題:用happen-before規則重新審視DCL h

c++中的 模式(singleton)和雙檢測鎖(Double-Checked Locking)

今天學習了一下c++中的singleton。google了一篇論文C++ and the Perils of Double-Checked Locking。大名鼎鼎的Scott Meyers寫的。論文使用c++講解,看了之後受益匪淺。 巧的是,讀完之後剛好看見http://

模式

實現 程序 先來 null effective 如果 ava 不同的 aps 單例模式:確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 優點: 1、省略創建對象所花費的時間減少系統開銷,尤其是重量級對象。 2、減少對象的創建,減輕GC壓力。 3、設置全局

GOF23—模式(2)

應該 一個 img bsp 漏洞 資源 nbsp 創建 就會 本文介紹單例模式(不包含枚舉單例模式)漏洞問題以及如何防止漏洞   1.反射可以破解單例模式,例子如下:       此時,我們運行Client類,發現s1和s2是一個對象,但s3和s4是不同的對象。 那麽如何防

溫故而知新(java實現)模式的七種寫法

反序 防止 代碼 工作 html 我想 變種 evel 才會 第一種(懶漢,線程不安全): Java代碼 public class Singleton { private static Singleton instance; private S

模式和線程安全

tac 可能 存在 版本 線程不安全 廣東 多線程 一個 單例 前幾天給項目的省市區加了redis。結果上線沒多久就發生了數據錯亂的現象,需要讀取山東省的市可能返回的市廣東的。一開始不明白哪裏有問題,因為測試組的同學有測試過,在測試過程種並沒有發生這樣的情況。由於使用了se

C#模式的多種寫法

code if語句 規則 最簡 lock 實現 readonly led 三種 它的主要特點不是根據客戶程序調用生成一個新的實例,而是控制某個類型的實例數量-唯一一個。(《設計模式-基於C#的工程化實現及擴展》,王翔)。也就是說,單例模式就是保證在整個應用程序的生命周期中,

Swift、Objective-C 模式 (Singleton)

app 賦值 uil imp ide 效果 func instance 發現 本文的單例模式分為嚴格單例模式和不嚴格單例模式。單例模式要求一個類有一個實例,有公開接口可以訪問這個實例。嚴格單例模式,要求一個類只有一個實例;不嚴格單例模式,可以創建多個實例。 有的類只能有一個

模式-Singleton

加載 null 允許 nbsp 訪問 加載類 public tin style 單例模式:保證一個類僅有一個實例,並提一個訪問它的全局訪問點。   通常我們可以讓一個全局變量使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法就是,讓類自身負責保存它的唯一實例。

[轉]設計模式--模式(一)懶漢式和餓漢式

打印 是否 調用構造 餓漢 一段 tools 會有 輸出結果 java 單例模式是設計模式中比較簡單的一種。適合於一個類只有一個實例的情況,比如窗口管理器,打印緩沖池和文件系統, 它們都是原型的例子。典型的情況是,那些對象的類型被遍及一個軟件系統的不同對象訪問,因此需要一個

23種設計模式介紹以及模式的學習

單例模式 餓漢式 23種設計模式 gof23 1、GOF23 設計模式總共分成創建型模式、結構型模式和行為型模式三種: a、創建型模式: - 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式 b、構建型模式: - 適配器模式、橋接模式、裝配模式、組合模式、建造者模

c++之模式

lsi 但是 desc 模式 單例模式 ron spl 希望 構造函數 1 本篇主要討論下多線程下的單例模式實現:   首先是 double check 實現方式: 這種模式可以滿足多線程環境下,只產生一個實例。 template<typename T>