單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。設計模式
這種模式涉及到一個單一的類,該類負責建立本身的對象,同時確保只有單個對象被建立。這個類提供了一種訪問其惟一的對象的方式,能夠直接訪問,不須要實例化該類的對象。安全
注意:多線程
單例模式的實現有多種方式,以下所示:性能
是否 Lazy 初始化:是線程
是否多線程安全:否設計
實現難度:易對象
描述:這種方式是最基本的實現方式,這種實現最大的問題就是不支持多線程。由於沒有加鎖 synchronized,因此嚴格意義上它並不算單例模式。
這種方式 lazy loading 很明顯,不要求線程安全,在多線程不能正常工做。教程
public class Singleton { 內存
private static Singleton instance; ssl
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
} return instance; }
}
接下來介紹的幾種實現方式都支持多線程,可是在性能上有所差別。
是否 Lazy 初始化:是
是否多線程安全:是
實現難度:易
描述:這種方式具有很好的 lazy loading,可以在多線程中很好的工做,可是,效率很低,99% 狀況下不須要同步。
優勢:第一次調用才初始化,避免內存浪費。
缺點:必須加鎖 synchronized 才能保證單例,但加鎖會影響效率。
getInstance() 的性能對應用程序不是很關鍵(該方法使用不太頻繁)。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); }
return instance; }
}
是否 Lazy 初始化:否
是否多線程安全:是
實現難度:易
描述:這種方式比較經常使用,但容易產生垃圾對象。
優勢:沒有加鎖,執行效率會提升。
缺點:類加載時就初始化,浪費內存。
它基於 classloader 機制避免了多線程的同步問題,不過,instance 在類裝載時就實例化,雖然致使類裝載的緣由有不少種,在單例模式中大多數都是調用 getInstance 方法, 可是也不能肯定有其餘的方式(或者其餘的靜態方法)致使類裝載,這時候初始化 instance 顯然沒有達到 lazy loading 的效果。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance; } }
JDK 版本:JDK1.5 起
是否 Lazy 初始化:是
是否多線程安全:是
實現難度:較複雜
描述:這種方式採用雙鎖機制,安全且在多線程狀況下能保持高性能。
getInstance() 的性能對應用程序很關鍵。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton(); }
}
}
return singleton; }
}
以上內容來自菜鳥教程設計模式——單例模式