【JAVA】設計模式 單例模式的五種代碼

單例模式

單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。

這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。

注意:

1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。

懶漢模式(線程不安全方式 不推薦 新手一般會這麼寫)

/**
 * 懶漢模式
 * 單例實例在第一次使用時被創建 容易出bug 線程不安全的
 */
public class SingletonExample {
    //私有構造對象
    private  SingletonExample(){

    }
    //單例對象
    private  static  SingletonExample instance = null;
    //靜態工廠方法
    public  static  SingletonExample getInstance(){
        if(instance == null){
            instance = new SingletonExample();
        }
        //這種方法 == null 在單線程下沒什麼問題,多線程下容易出現問題,因爲可能同時有兩個以上的線程走到if裏
        return  instance;
    }
}

懶漢模式(線程安全方式,加synchronized 不推薦)

/**
 * 懶漢模式
 * 單例實例在第一次使用時被創建  加了synchronized有開銷
 */
@ThreadSafe
public class SingletonExample3 {
    //私有構造對象
    private SingletonExample3(){

    }
    //單例對象
    private  static SingletonExample3 instance = null;
    //靜態工廠方法  有性能開銷
    public  static  synchronized  SingletonExample3 getInstance(){
        if(instance == null){
            instance = new SingletonExample3();
        }
        return  instance;
    }
}

懶漢模式(雙重檢測,但是仍然線程不安全原因是多線程下指令重排!!)


/**
 * 懶漢模式 -》 雙重同步鎖單例模式
 * 單例實例在第一次使用時被創建
 */
public class SingletonExample4 {
    //私有構造對象
    private SingletonExample4(){

    }

    //1。memory = allocate() 分配對象內存空間
    //2。ctoInstance() 初始化對象
    //3。instance = memory 設置instance指向剛分配的內存

    //JVM和cpu優化 多線程下發生了指令重排
    //1。memory = allocate() 分配對象內存空間
    //3。instance = memory 設置instance指向剛分配的內存
    //2。ctoInstance() 初始化對象

   // 雙重檢測機制出現問題


    //單例對象
    private  static SingletonExample4 instance = null;
    //靜態工廠方法  有性能開銷
    public  static   SingletonExample4 getInstance(){
        if(instance == null){//雙重檢測機制  //B
            synchronized(SingletonExample.class) {//同步鎖
                if (instance == null){
                    instance = new SingletonExample4(); // A線程執行到這時,完成了 指令的 1 ,3 還沒進行初始化。這是B那個位置發現已經不爲null了直接就返回回去了。但是 真實的時instance還沒初始化完。
                }
            }
        }
        return  instance;
    }
}

懶漢模式(雙重檢測,加volatile 禁止指令重排, 推薦 )

/**
 * 懶漢模式 -》 雙重同步鎖單例模式
 * 單例實例在第一次使用時被創建
 */
public class SingletonExample5 {
    //私有構造對象
    private SingletonExample5(){

    }

    //1。memory = allocate() 分配對象內存空間
    //2。ctoInstance() 初始化對象
    //3。instance = memory 設置instance指向剛分配的內存

    //限制發生指令重排
    //單例對象 volatile 加上雙重檢測機制來禁止 指令重排
    private  volatile  static SingletonExample5 instance = null;
    //靜態工廠方法  有性能開銷
    public  static SingletonExample5 getInstance(){
        if(instance == null){//雙重檢測機制  //B
            synchronized(SingletonExample.class) {//同步鎖
                if (instance == null){
                    instance = new SingletonExample5(); // A
                }
            }
        }
        return  instance;
    }
}

餓漢模式(推薦)

/**
 * 餓漢模式
 * 單例實例類裝載時進行創建 不足當單例模式過多時,可能會影響性能問題,如果最終沒調用,會造成資源浪費。  線程安全的
 */
public class SingletonExample2 {
    //私有構造對象
    private  SingletonExample2(){

    }
    //單例對象
    private  static  SingletonExample2 instance = new SingletonExample2();
    //靜態工廠方法
    public  static  SingletonExample2 getInstance(){
        return  instance;
    }
}

餓漢模式(推薦)

/**
 * 餓漢模式
 * 單例實例類裝載時進行創建
 */
public class SingletonExample6 {
    //私有構造對象
    private SingletonExample6(){

    }
    //單例對象
    private  static SingletonExample6 instance = null;

    static {
        instance = new SingletonExample6();
    }

    //靜態工廠方法
    public  static SingletonExample6 getInstance(){
        return  instance;
    }
    public static void main(String[] args) {
        System.out.println(getInstance());
        System.out.println(getInstance());
    }

}

枚舉(最安全 最推薦)

/**
 * 枚舉模式 最安全
 */
public class SingletonExample7 {
    private  SingletonExample7(){
    }
    public static  SingletonExample7 getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
    
    //私有枚舉類  
    private  enum Singleton{
        INSTANCE;
        private  SingletonExample7 singleton;
        //JVM 保證這個方法絕對只調用一次
        Singleton(){
            singleton = new SingletonExample7();
        }
        public SingletonExample7 getInstance(){
            return  singleton;
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章