線程安全的單例模式
----------------------
經典的單例模式安全
1 public class Singleton{ 2 private static Singleton uniqueInstance; 3 private static Singleton(){} 4 public static Singleton getInstance(){ 5 if(uniqueInstance == null) 6 uniqueInstance = new Singleton() 7 return uniqueInstance; 8 } 9 }
經典的單例模式是線程不安全的,若是多個併發線程同時調用getInstance()方法就有可能生成多個實例。下面介紹幾種實現線程安全的單例模式
使用synchronized修飾getInstance()方法併發
1 public class Singleton{ 2 private static Singleton uniqueInstance; 3 private static Singleton(){} 4 public static synchronized Singleton getInstance(){ 5 if(uniqueInstance == null) 6 uniqueInstance = new Singleton() 7 return uniqueInstance; 8 } 9 }
使用這種方法簡單易懂但效率很是低,不推薦使用。
使用急切建立實例,而不使用延遲初始化async
1 public class Singleton{ 2 private static Singleton uniqueInstance = new Singleton(); 3 private static Singleton(){} 4 public static Singleton getInstance(){ 5 return uniqueInstance; 6 } 7 }
若是建立該實例不是那麼昂貴的話,就使用該模式吧。
若是出於性能考慮而須要使用延遲初始化,就使用 lazy initialization holder class模式,這種模式也被稱爲initialize-demand holder class idiom,保證了實例要被建立的時候才初始化。性能
public class Singleton{ private static class SingletonHolder{ private static Singleton uniqueInstance = new Singleton(); } private static Singleton(){} public static Singleton getInstance(){ return SingletonHolder.uniqueInstance; } }
使用雙重檢測模式,即保證了同步,有不會下降明顯的性能。spa
1 public class Singleton{ 2 private static Singleton uniqueInstance; 3 private staticSingleton(){} 4 public static Singleton getInstance(){ 5 if(uniqueInstance == null){ 6 asynchronized(Singleton.class){ 7 if(uniqueInstance == null){ 8 uniqueInstance = new Singleton() 9 } 10 } 11 } 12 } 13 return uniqueInstance; 14 }
這幾種模式推薦使用3或者4,更或者直接使用模式3,即保證了線程的安全,又沒有任何性能的下降,並且提供了延遲初始化。線程
不支持Marketdown因此顯示有點亂。code