首頁 > 軟體

詳解Java中的八種單例建立方式

2022-02-11 16:00:41

定義

單例設計模式,就是採取一定的方法保證在整個的軟體系統中,對某個類只能存在一個物件範例,並且該類只提供一個取得其物件範例的方法(靜態方法)

使用場景

  • 對於一些需要頻繁建立銷燬的物件
  • 重量級的物件
  • 經常使用到的物件
  • 工具類物件
  • 資料來源
  • session

單例模式八種方式

餓漢式(靜態常數)

程式碼

/**
 * 餓漢式(靜態常數)
 * 優勢:簡單,避免多執行緒的同步問題
 * 劣勢:無懶載入,記憶體浪費
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton1 {
    // 私有化構造方法
    private Singleton1(){}

    // 靜態常數
    private static final Singleton1 singleton1 = new Singleton1();

    // 對外提供公共方法
    public static Singleton1 getSingleton1(){
        return singleton1;
    }
}

分析

  • 優勢:簡單,避免多執行緒的同步問題
  • 劣勢:無懶載入,記憶體浪費

餓漢式(靜態程式碼塊)

程式碼

/**
 * 餓漢式(靜態程式碼塊)
 * 優勢:簡單,避免多執行緒的同步問題
 * 劣勢:無懶載入,記憶體浪費
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton2 {
    // 私有化構造方法
    private Singleton2(){}

    private static final Singleton2 singleton2;

    // 靜態程式碼塊
    static {
        singleton2 = new Singleton2();
    }

    // 對外提供公共方法
    public static Singleton2 getSingleton2(){
        return singleton2;
    }
}

分析

  • 優勢:簡單,避免多執行緒的同步問題
  • 劣勢:無懶載入,記憶體浪費

懶漢式(執行緒不安全)

程式碼

/**
 * 懶漢式(執行緒不安全)
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton3 {
    // 私有化構造方法
    private Singleton3(){}

    // 內部屬性
    private static Singleton3 singleton3;

    // 對外提供公共方法
    public static Singleton3 getSingletons(){
        if(singleton3 == null){
            singleton3 = new Singleton3();
        }
        return singleton3;
    }
}

分析

  • 優勢:起到了懶載入的效果 不會造成記憶體浪費
  • 劣勢:執行緒不安全 不推薦這種方式的

懶漢式(同步方法)

程式碼

/**
 * 懶漢式(同步方法)
 * 優勢:解決了執行緒同步問題
 * 劣勢:使用synchronized同步關鍵字,效能太低
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton4 {
    // 私有化構造方法
    private Singleton4(){}

    // 內部屬性
    private static Singleton4 singleton4;

    // 對外提供公共方法
    public static synchronized Singleton4 getSingleton4(){
        if(singleton4 == null){
            singleton4 = new Singleton4();
        }
        return singleton4;
    }
}

分析

  • 優勢:解決了執行緒安全問題,
  • 劣勢:效率太低

懶漢式(同步程式碼塊)

程式碼

/**
 * 懶漢式(同步程式碼塊)
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton5 {
    // 私有化構造方法
    private Singleton5(){}

    // 內部屬性
    private static Singleton5 singleton5;

    // 對外提供公共方法
    public static Singleton5 getSingleton5(){
        if (singleton5 == null){
            synchronized (Singleton5.class){
                singleton5 = new Singleton5();
            }
        }
        return singleton5;
    }
}

分析

  • 優勢:起到了懶載入的效果 不會造成記憶體浪費
  • 劣勢:執行緒不安全 不推薦這種方式的

雙重檢查鎖方式

程式碼

/**
 * 雙重檢查鎖機制
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton6 {
    // 私有化構造方法
    private Singleton6(){}

    // 內部屬性
    private volatile static Singleton6 singleton6;

    // 對外提供公共方法
    public static Singleton6 getSingleton6(){
        if (singleton6 == null){
            synchronized (Singleton6.class){
                if(singleton6 == null){
                    singleton6 = new Singleton6();
                }
            }
        }
        return singleton6;
    }
}

分析

  • 實現了懶載入,效率很高,解決了執行緒安全

靜態內部類方式

程式碼

/**
 * 靜態內部類
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
public class Singleton7 {
    // 私有化構造方法
    private Singleton7(){}

    // 內部類
    private static class SingleInstance{
        public static final Singleton7 singleton7 = new Singleton7();
    }

    // 對外提供公共方法
    public static Singleton7 getSingleton7(){
        return SingleInstance.singleton7;
    }
}

分析

  • 不會出現執行緒安全問題 JVM來幫我們保證了執行緒的安全性
  • 利用靜態內部類的特點,效率也很高,
  • 實際開發中推薦使用的

列舉方式

程式碼

定義單例物件

/**
 * @desc:
 * @author:liyajie
 * @createTime:2022/2/11 10:25
 * @version:1.0
 */
public class Singleton {

    public void hello(){
        System.out.println("hello");
    }
}

定義列舉範例化單例物件

/**
 * 列舉方式
 * @author:liyajie
 * @createTime:2022/2/10 15:50
 * @version:1.0
 */
enum Singleton8 {
    // 相當於public static final Singleton8 INSTANCE;
    // 保證了列舉範例只能被範例化一次
    INSTANCE;

    // 定義單例變數
    private Singleton singleton;

    // 列舉構造方法,該構造方法是private,執行構造方法的時候,同時建立我們的單例物件
    Singleton8() {
        singleton = new Singleton();
    }

    // 對外提供公共方法
    public Singleton getSingleton() {
        return singleton;
    }
}

使用方法Singleton8.INSTANCE.getSingleton()即可獲取我們的單例物件了

分析

  • 簡單,避免了執行緒安全問題
  • 實際開發中推薦使用的

總結

1.單例模式保證了系統記憶體中該類只存在一個物件,節省了系統資源,對於一些需要頻繁建立銷燬的物件, 使用單例模式可以提高系統效能

2.當想範例化一個單例類的時候,必須要記住使用相應的獲取物件的方法,而不是使用new

3.單例模式推薦使用的方法有內部靜態類方式和列舉方式

到此這篇關於詳解Java中的八種單例建立方式的文章就介紹到這了,更多相關Java單例建立方式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com