Java多線程編程核心技術第六章筆記:單例模式與多線程;懶漢模式在多線程之下的好多種解決方式

1、立即加載/“餓漢模式”:

沒啥寫的就不寫了;太easy;

2、延遲加載/“懶漢模式”

延遲加載在多線程中根本不可能保持單例的狀態,如示例:加載出了三個實例對象:

3、懶漢模式的解決方案1:聲明synchronized關鍵字;

給getInstance方法加上synchronized關鍵字解決多線程下的懶漢模式問題
這種方法的缺點:運行效率非常低下,因爲他是同步運行的;
在這裏插入圖片描述

4、懶漢模式的解決方案2:嘗試同步代碼塊

嘗試同步代碼塊:同樣效率低下:
在這裏插入圖片描述

5、懶漢模式的解決方案3:針對某些關鍵的代碼進行單獨的同步:

在這裏插入圖片描述

懶漢模式的解決方案4:使用DCL雙檢查鎖機制(Double Check Locking)來實現多線程環境中的延遲加載單例設計模式;

在這裏插入圖片描述
代碼:

package Day01.Test;


/**
* @author Dangxuchao
* @Title: Test7
* @ProjectName 6.1 Java多線程編程核心技術第六章 :單例模式與多線程
* @Description: 延遲加載的解決方案4:
*  使用DCL雙檢查鎖機制來實現多線程環境中的延遲加載單例設計模式;
* @date 2019/6/7 10:14
*/


class MyObject7 {
    private static volatile MyObject7 myObject7;//volatile避免指令重排序
    public MyObject7() {
    }
    public static MyObject7 getInstance(){
        if (myObject7 == null){
            synchronized (MyObject7.class){
                if (myObject7 == null){
                    myObject7 = new MyObject7();
                }
            }
        }
        return myObject7;
    }
}
class Thread7 extends Thread{
    @Override
    public void run() {
        System.out.println(MyObject7.getInstance().hashCode());
    }
}
public class Test7 {
    public static void main(String[] args) {
        Thread7 t1 = new Thread7();
        Thread7 t2 = new Thread7();
        Thread7 t3 = new Thread7();
        t1.start();
        t2.start();
        t3.start();
    }
}
/*
運行結果:
    1211537232
    1211537232
    1211537232
*/
7、懶漢模式的解決方案5:使用靜態內置類實現單例模式:

在這裏插入圖片描述

懶漢模式的解決方案5:序列化與反序列化實現;

內置類可以達到線程安全問題,但是如果遇到序列化對象時,使用默認的方式運行得到的結果還是多例的;

package Day01.Test;


import java.io.*;


/**
* @author Dangxuchao
* @Title: Test9
* @ProjectName 6.1 Java多線程編程核心技術第六章 :單例模式與多線程
* @Description: 8、懶漢模式的解決方案5:序列化與反序列化實現;
* @date 2019/6/7 10:49
*/

class MyObject9 implements Serializable{
    private static final long serialVersionUID = 888L;
    private static class MyObject9Handler{
        private static final MyObject9 object9 = new MyObject9();
    }

    public MyObject9() {
    }
    public static MyObject9 getInstance(){
        return MyObject9Handler.object9;
    }
    protected Object readResolve(){
        System.out.println("調用了方法");
        return MyObject9Handler.object9;
    }
}
public class Test9 {
    public static void main(String[] args) {
        try{
            MyObject9 myObject9 = MyObject9.getInstance();
            FileOutputStream fosRef = new FileOutputStream(
                    new File("C:\\Users\\dangwuxie\\Desktop\\6-7.txt"));
            ObjectOutputStream oosRef = new ObjectOutputStream(fosRef);
            oosRef.writeObject(myObject9);
            oosRef.close();
            fosRef.close();
            System.out.println(myObject9.hashCode());


        }catch (FileNotFoundException a){
            a.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }

        try {
            FileInputStream fisRef = new FileInputStream(
                    new File("C:\\Users\\dangwuxie\\Desktop\\6-7.txt"));
            ObjectInputStream iosRef = new ObjectInputStream(fisRef);
            MyObject9 myObject9 = (MyObject9) iosRef.readObject();
            iosRef.close();
            fisRef.close();
            System.out.println(myObject9.hashCode());
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}
/*
運行結果:

    1173230247
    調用了方法
    1173230247


*/
9、懶漢模式的解決方案6:使用static代碼塊實現單例模式;(跟內部類是差不多的)

在這裏插入圖片描述

10、懶漢模式的解決方案7:使用enum枚舉數據類型實現單例模式,枚舉enum和靜態代碼塊的特性相似;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章