Java中建立單例模式的五種方法及執行緒安全

2021-07-22 09:49:20 字數 3171 閱讀 6100

單例模式在日常工程專案中應用十分廣泛,但是如果沒有考慮執行緒安全的問題,可能會在多執行緒環境下產生錯誤的結果,生成多個例項。

以下兩個類,是本次實驗中用到的兩個公共類,singletonfactory用於建立各種單例物件,singletontest用於測試各種單例模式的執行緒安全性。

public

inte***ce singletonfactory

public

static singletondcl getsingletondcl()

public

static singletonstaticblock getsingletonstaticblock()

public

static singletoninnerstaticclass getsingletoninnerstaticclass()

public

static singletoninnerenum getsingletoninnerenum()

public

static singletonwrong getsingletonwrong()

}

public

class singletontest

};for (int i = 0; i < 5; i++) }}

以下將要展示的是一種錯誤的單例模式。

public

class singletonwrong

public

static singletonwrong getinstance()

} catch (interruptedexception e)

return instance;}}

該程式在測試環境中執行結果如下:

從hashcode我們可以看出,多執行緒使用單例模式時,此種方法並沒有達到單例的效果,而是建立了多個例項。

1. 使用「立即載入」模式:

public

class singletonimit

public

static singletonimit getinstance()

}

該實現在測試環境中執行結果如下:

從結果上我們可以看到,多執行緒下達到了獲得單例的目的。不過此種方式的缺陷在於:在類載入過程中就已經將具體的物件建立完畢,如果物件很大,會提前一直占用著記憶體。

2. 使用「延時載入」實現執行緒安全的單例模式:

public

class singletondcl

public

static singletondcl getinstance()

}} catch (interruptedexception e)

return instance;}}

在測試環境中執行結果如下:

此種方式實際上是對上面展示的「錯誤示範」的一種改進,可以看到,新的實現方式達到了單例的目的。

3. 利用靜態內部類實現執行緒安全的單例模式:

public

class

singletoninnerstaticclass

implements

serializable

private

static

class

singlehandler

public

static singletoninnerstaticclass getinstance()

protected object readresolve() throws objectstreamexception

}

該實現方式在測試環境中執行結果如下:

此種方式需要注意的是在單例物件需要序列化時,需要重寫protect object readresolve()方法。

4. 利用「靜態**塊」實現單例模式:

public

class singletonstaticblock

private

singletonstaticblock()

public

static singletonstaticblock getinstance()

}

此實現方式在測試環境中執行結果如下:

此種實現方法與「立即載入」的原理基本相同,都是利用類載入時的初始化操作實現的。

5. 利用「內部列舉型別」實現執行緒安全的單例模式:

public

class singletoninnerenum

public

enum instance catch (interruptedexception e)

}public singletoninnerenum getinstance()

}public

static singletoninnerenum getinstance()

}

此方法在測試環境中結果如下:

可以從結果看到,此種方式確實能夠在多執行緒環境下實現單例的目的。

上面雖然介紹了五種實現單例模式的方法,但只是具體的實現方式不同,實質上只有「立即載入」與「延遲載入」兩種。特別需要注意的是使用「延遲載入」時,需要兩重檢測,否則即使存在同步塊,也無法保證執行緒安全。

Java中的五種單例模式

解法一 只適合單執行緒環境 不好 public class singleton public static singleton getinstance return instance 註解 singleton的靜態屬性instance中,只有instance為null的時候才建立乙個例項,建構函式私...

java之五種單例模式

餓漢模式 dcl double check lock 雙重校驗鎖 靜態內部類 列舉單例 選擇方式 執行緒安全 效率延遲載入 懶漢模式 安全 方法加鎖 低 方法加鎖 能 物件空才例項化 餓漢模式 安全 初始化載入 高 無鎖 不能 類初始化就已經載入 dcl模式 安全 塊加鎖 高 僅第一次加鎖 能 物件...

五種單例模式

import settings class mysql instance none 原始狀態設為none def init self,ip,port self.ip ip self.port port classmethod deffrom conf cls if cls.instance is n...