單例模式在日常工程專案中應用十分廣泛,但是如果沒有考慮執行緒安全的問題,可能會在多執行緒環境下產生錯誤的結果,生成多個例項。
以下兩個類,是本次實驗中用到的兩個公共類,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...