單列模式

一、什麼是單列模式設計模式

單列模式(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來實現

相關文章
相關標籤/搜索