確保一個特定的類只有一個對象被實例化。
Singleton:用於單線程應用程序
Double-Checked Locking在java實際上無法得到預期的效果,不能保證singleton的正確性。
參考:(英文)
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
餓漢式
public class Singleton {
private Singleton() {
}
// 在自己內部定義自己一個實例,是不是很奇怪?
// 注意這是private 只供內部調用
private static Singleton instance = new Singleton();
// 這裏提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}
懶漢式
public class Singleton {
private Singleton() {
}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)
instance=new Singleton();
return instance;
}
}
使用Singleton注意事項:
有時在某些情況下,使用Singleton並不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分佈式系統中使用也要注意這種情況,因爲EJB是跨服務器,跨JVM的。
我們以SUN公司的寵物店源碼(Pet Store 1.3.1)的ServiceLocator爲例稍微分析一下:
在Pet Store中ServiceLocator有兩種,一個是EJB目錄下;一個是WEB目錄下,我們檢查這兩個ServiceLocator會發現內容差不多,都是提供EJB的查詢定位服務,可是爲什麼要分開呢?仔細研究對這兩種ServiceLocator才發現區別:在WEB中的ServiceLocator的採取Singleton模式,ServiceLocator屬於資源定位,理所當然應該使用Singleton模式。但是在EJB中,Singleton模式已經失去作用,所以ServiceLocator才分成兩種,一種面向WEB服務的,一種是面向EJB服務的。
Singleton模式看起來簡單,使用方法也很方便,但是真正用好,是非常不容易,需要對Java的類 線程 內存等概念有相當的瞭解。
總之:如果你的應用基於容器,那麼Singleton模式少用或者不用,可以使用相關替代技術。