做j2ee如果不懂單例模式和線程池慢慢就是白學了。
線程池到處都能看到,httpsession,數據庫連接池,redis連接池,MQ連接池。。。
使用場景:頻繁使用且創建本消耗高
多線程環境下,使用場景隨處可見...
餓漢式和懶漢式
名詞懶得解釋了。。。
懶漢式需要雙重鎖定
餓漢式沒線程安全問題
1,雙鎖單例模式,懶漢式
1 /// 定義一個全局訪問點 2 /// 設置為靜態方法 3 /// 則在類的外部便無需實例化就可以調用該方法 4 public static Singleton GetInstance() 5 { 6 //這里可以保證只實例化一次 7 //即在第一次調用時實例化 8 //以后調用便不會再實例化 9 //第一重 singleton == null 10 if (singleton == null) 11 { 12 lock (syncObject) 13 { 14 //第二重 singleton == null 15 if (singleton == null) 16 { 17 singleton = new Singleton(); 18 } 19 } 20 } 21 return singleton; 22 } 23 24
2,靜態工廠方法,也是餓漢式最簡單寫法。
1 public class Singleton{ 2 //initailzed during class loading 3 private static final Singleton INSTANCE = new Singleton(); 4 5 //to prevent creating another instance of Singleton 6 private Singleton(){} 7 8 public static Singleton getSingleton(){ 9 return INSTANCE; 10 } 11 }
spring配置的sessionFactory \DataSource都是默認單例。例如:
1 //獲取spring創建的bean對象 2 public synchronized static MyCache getInstance() { 3 4 return ServletUtil.getApplicationContext().getBean( MyCache.class); 5 6 }
3,序列化對象,枚舉實現單例基本是炫技,
最后:
單核心的多線程,不會有2個線程同時進入if判斷,本質還是一個線程。但多核心的,就完全可能2線程同時一個if判斷。
單例的范圍:
本文的單例的范圍是AppDomain.
要在一個AppDomain中保持單例的辦法是, 只在Main()中new這個對象一次, 然后把這個對象的引用賦值給所用使用它的對象.
如果要在操作系統中實現單例, 就需要使用Mutex(對象互斥鎖)了。一個程序只允許運行一個實例,即不能多開。在我寫C#桌面程序時經常用到。
要在一個AppDomain中保持單例的辦法是, 只在Main()中new這個對象一次, 然后把這個對象的引用賦值給所用使用它的對象.
如果要在操作系統中實現單例, 就需要使用Mutex(對象互斥鎖)了。一個程序只允許運行一個實例,即不能多開。在我寫C#桌面程序時經常用到。
如果要在Internet上實現單例, 可以使用URL唯一.
