本篇博客轉載自: 點擊打開鏈接 http://www.cnblogs.com/fernandolee24/p/5366720.html
public class LazySignleton {
private volatile static LazySignleton INSTANCE
= null;
private LazySignleton(){ }
pbulic static synchronized LazySignleton getInstance(){
if(INSTANCE == null)
INSTANCE = new LazySignleton();
return INSTANCE;
}
}
3、懶漢式的改進
當然既然懶漢式有這個缺點,我們可以單獨對其處理,如果實例已經創建過了,就不需要進行加鎖了,如下是改良後的實例方式:
public static LazySignleton getInstance(){
if(INSTANCE == null){
synchronized(LazySignleton.class){
if(INSTANCE == null){
INSTANCE = new LazySignleton();
}
}
}
return INSTANCE;
}
public class SafeSingleton implements Serializable,
Cloneable { private static final long serialVersionUID
= -4147288492005226212L; private static SafeSingleton
INSTANCE = new SafeSingleton(); private SafeSingleton()
{ if (INSTANCE
!= null )
{ throw new IllegalStateException( "Singleton
instance Already created." ); } } public static SafeSingleton
getInstance() { return INSTANCE; } private Object
readResolve() throws ObjectStreamException
{ return INSTANCE; } public Object
clone() throws CloneNotSupportedException
{ throw new CloneNotSupportedException( "Singleton
can't be cloned" ); } } |
在原有Singleton的基礎上完善若干方法即可實現一個安全的更爲純正的Singleton。注意到當實例已經存在時試圖通過調用私有構造函數會直接報錯從而抵禦了反射機制的入侵; 讓調用clone方法直接報錯避免了實例被克隆;覆寫readReslove方法直接返回現有的實例本身可以防止反序列化過程中生成新的實例。而對於不同類加載器導致的單例模式破壞暫未找到切實可行的應對方案,請大牛提供高見。
2、Enum Signleton
public enum EnumSingleton{ INSTANCE; private EnumSingleton(){ } } |
採用枚舉的方式實現Singleton非常簡易,而且可直接通過EnumSingleton.INSTANCE獲取該實例。Java中所有定義爲enum的類內部都繼承了Enum類,而Enum具備的特性包括類加載是靜態的來保證線程安全,而且其中的clone方法是final的且直接拋出CloneNotSupportedException異常因而不允許拷貝,同時與生俱來的序列化機制也是直接由JVM掌控的並不會創建出新的實例,此外Enum不能被顯式實例化反射破壞也不起作用。當然它也不是沒有缺點,比如由於已經隱式繼承Enum所以無法再繼承其他類了(Java的單繼承模式限制),而且相信大多數人並不樂意僅僅爲了實現一個純正的Singleton就將習慣的class修改爲enum。