一、什麼是單列模式設計模式
單列模式(Singleton)保證一個類僅有一個實例,並提供一個訪問的全局訪問點,這種類型的設計模式屬於建立型模式。在開發中,會常常遇到一個全局使用的類頻繁地建立與銷燬,這會很是浪費系統的內存資源,並且容易致使錯誤甚至必定會產生錯誤,因此咱們單例模式所期待的目標或者說使用它的目的,是爲了儘量的節約內存空間,減小無謂的GC消耗,而且使應用能夠正常運做。 安全
二、實現方式bash
2.一、懶漢模式,線程不安全多線程
最基本的實現方式,這種實現最大的問題就是不支持多線程。併發
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
複製代碼
針對懶漢模式線程不安全的問題,咱們天然想到了,在getInstance()方法前加鎖,因而就有了第二種實現性能
2.二、懶漢模式,線程安全ui
可以在多線程中很好的工做,打補丁方式寫出來的結構效率很低,多數狀況下不須要同步。spa
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
複製代碼
由於加了synchronized爲獨佔排他鎖,併發性能差,因而爲了解決這個問題又有第三種實現線程
2.三、餓漢式設計
在類加載的時候,就完成了對象的初始化,類加載保證了他們天生是線程安全的
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
複製代碼
沒有達到Lazy Loading的效果,若是從始至終從未使用過這個實例,則會形成內存的浪費,那如何解決這個問題呢?
2.四、靜態內部類
Singleton 類被裝載了,instance 不必定被初始化,只有在調用的時候才進行加載,達到了相似懶漢模式的效果,而這種方法又是線程安全的。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
複製代碼
2.五、枚舉
枚舉實現方式尚未被普遍採用,但這是實現單例模式的最佳方法。它更簡潔,自動支持序列化機制,絕對防止屢次實例化和線程安全的
public enum Singleton {
INSTANCE;
public void action() {
}
}
調用
Singleton.INSTANCE.action();
複製代碼
2.六、雙重校驗鎖法
採用雙鎖機制,安全且在多線程狀況下能保持高性能
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;
}
}
複製代碼
三、總結
推薦使用3-6的實現方式,固然並非說1-2不能使用,具體的還須要根據業務場景來使用,例如不須要再多線程使用的能夠根據1來實現;須要支持序列化的可使用5來實現,通常狀況下建議使用3來實現