一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

23種設計模式入門 -- 單例模式

 小仙女本仙人 2021-07-07

單例模式:采用一定的方法,使得軟件運行中,對于某個類只能存在一個實例對象,并且該類只能提供一個取得實例的方法。

分類

  • 餓漢式

    1. 靜態(tài)常量方式

    2. 靜態(tài)代碼塊方式

  • 懶漢式

    1. 普通方式,線程不安全

    2. 同步方法方式,線程安全

    3. 同步代碼塊方式,線程不安全

  • 其他方式

    1. 雙重檢查

    2. 靜態(tài)內部類

    3. 枚舉

實現思路:

  1. 想要實現單例,即不能讓外部隨意的去實例化對象。所以需要構造器私有

  2. 既然不允許外部去創(chuàng)建了,所以需要在類的內部創(chuàng)建對象

  3. 外部需要使用對象,所以需要對外提供一個獲取實例的方法

一、餓漢式

根據對象創(chuàng)建的時機,可以分為餓漢式和懶漢式。餓漢式,即在類加載的時候立即創(chuàng)建實例,根據所學知識我們可以很快想到要使用static關鍵字將屬性和類相關聯。以下提供兩種書寫方式供參考。

特點

  • 優(yōu)點:寫法簡單,在類裝載的時候就完成實例化,避免了線程同步問題

  • 缺點:在類裝載的時候就完成了實例化,如果開始至終都沒有使用這個實例,會造成內存浪費

1.靜態(tài)常量方式

class Singleton01{
    //構造器私有,防止外部new
    private Singleton01(){

    }
    //內部創(chuàng)建對象
    private final static Singleton01 instance = new Singleton01();

    //提供給外部創(chuàng)建實例的靜態(tài)方法
    public static Singleton01 getInstance(){
        return instance;
    }

}

2.靜態(tài)代碼塊方式

class Singleton02{
    //構造器私有,防止外部new
    private Singleton02(){

    }
    //內部創(chuàng)建對象
    private static Singleton02 instance;
    static {
        instance = new Singleton02();
    }

    //提供給外部創(chuàng)建實例的靜態(tài)方法
    public static Singleton02 getInstance(){
        return instance;
    }

}

這種方式和靜態(tài)常量的實現方式邏輯和優(yōu)缺點是一樣的,只是寫法不同。

二、懶漢式

懶漢式,即在類加載時并不實例化對象,等到使用對象實例的時候才去實例化,也被稱為懶加載效果。這樣做的好處可以節(jié)約資源,減少浪費,只有需要的時候采取創(chuàng)建,不需要就不會實例化。

1.普通方式(線程不安全)

class Singleton01{
    // 構造器私有
    private Singleton01(){

    }
    // 定義靜態(tài)變量,實例化留在獲取實例的getInstance方法,起到懶加載效果
    private static Singleton01 instance;

    public static Singleton01 getInstance(){
        // 判斷如果為空才創(chuàng)建,起到懶加載
        if (instance == null){
            instance = new Singleton01();
        }

        return instance;
    }
}

問題:在多線程情況下,假設類還未第一次實例化,此時兩個進程同時執(zhí)行到了if(instance==null),而未來得及往下執(zhí)行時,此時兩者校驗都成立,都會執(zhí)行實例化操作,將有可能出現創(chuàng)建多個實例的問題。

2.同步方法方式(線程安全)

既然存在線程安全問題,肯定會想到使用synchronized關鍵字來解決

class Singleton02{
    private static Singleton02 instance;

    private Singleton02(){

    }
    //使用synchronized關鍵字來實現線程安全
    public static synchronized Singleton02 getInstance(){
        if (instance == null){
            instance = new Singleton02();
        }
        return instance;
    }
}

這樣的方式可以起到線程安全的效果,但是每個線程都需要等待鎖,所以又會存在效率低的問題,于是有人想到了將鎖的范圍縮小到方法的內部,使用同步代碼塊的方式

3.同步代碼塊方式(線程不安全)

這樣的方式好不好呢?先看代碼

class Singleton03{
    private static Singleton03 instance;

    private Singleton03(){

    }

    public static Singleton03 getInstance(){
        if (instance == null){
            // 這里的synchronized其實沒有實際意義,可能會產生多個實例
            synchronized (Singleton03.class){ 
                instance = new Singleton03();
            }
        }
        return instance;
    }
}

這樣鎖的范圍是變小了,但是還會存在多個線程同時判斷到if (instance == null),即使在后面加上鎖,依舊會在后續(xù)創(chuàng)建實例,只是延遲了一點而已,所以這種寫法不可取

三、其他方式

1.雙重檢查

為了能夠實現懶加載的效果,同時兼顧效率,于是出現了這種寫法

class Singleton01{
    //volatile,當有發(fā)生變化時即時儲存到內存中。防止指令重排
    private static volatile Singleton01 instance;

    private Singleton01(){

    }

    //雙重檢查,解決線程同步問題,又保證效率
    public static Singleton01 getInstance(){
        if (instance == null){ // 第一次檢查,降低產生鎖的概率
            synchronized (Singleton01.class){
                if(instance == null){ // 第二次檢查,保證線程安全
                    instance = new Singleton01();
                }
            }
        }
        return instance;
    }
}

使用雙重檢查,第一次檢查提升效率,第二次檢查保證線程安全,簡直美滋滋

2.靜態(tài)內部類

利用靜態(tài)內部類在被調用時才會加載,即存在懶加載效果,所以也可以這樣寫

class Singleton02{
    private Singleton02(){

    }

    /*
        靜態(tài)內部類在外部類裝載的時候不會馬上執(zhí)行,起到懶加載作用。
        類的靜態(tài)屬性只有在第一次使用的時候才會加載,JVM在類加載時是線程安全的
     */
    private static class SingletonInstance{
        private static final Singleton02 INSTANCE = new Singleton02();
    }

    public static Singleton02 getInstance(){
        return SingletonInstance.INSTANCE;
    }

}

3.枚舉

枚舉方式是最簡單的寫法,也是被很多人推崇的寫法

enum Singleton03{
    INSTANCE;
}

簡單明了...

四、小結

使用單例模式,可以使一個類只存在一個實例對象,從而節(jié)省了系統(tǒng)資源。

上文中列出了8個寫法,其中懶加載的寫法存在線程安全和效率的問題,需要謹慎使用。比較推薦的寫法有5種:懶加載2種+其他方式3種。當認定單例的對象在軟件中一定會用到,可以使用懶加載,反之可以使用其他方式

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产精品一区二区视频大全| 国产农村妇女成人精品| 熟女体下毛荫荫黑森林自拍| 免费观看潮喷到高潮大叫| 亚洲男人天堂网在线视频| 中文字幕五月婷婷免费| 国产成人精品国产成人亚洲 | 国产一区二区三区成人精品| 国产在线不卡中文字幕| 一区二区三区在线不卡免费| 中文字字幕在线中文乱码二区| 男人大臿蕉香蕉大视频| 91久久精品中文内射| 神马午夜福利一区二区| 三级高清有码在线观看| 午夜福利精品视频视频| 福利专区 久久精品午夜| 视频一区二区黄色线观看| 国产欧美日韩综合精品二区| 国产内射一级二级三级| 日韩中文字幕视频在线高清版| 日韩欧美国产三级在线观看| 自拍偷拍一区二区三区| 色婷婷在线精品国自产拍| 好吊视频一区二区在线| 久久精品a毛片看国产成人| 麻豆国产精品一区二区三区| 国产日产欧美精品大秀| 国内九一激情白浆发布| 国产精品欧美日韩中文字幕| 国产成人精品一区在线观看| 日本中文在线不卡视频| 日韩欧美好看的剧情片免费| 热情的邻居在线中文字幕| 亚洲一区二区亚洲日本| 午夜色午夜视频之日本| 男女午夜在线免费观看视频| 韩日黄片在线免费观看| 在线视频三区日本精品| 九九热精彩视频在线播放| 麻豆精品在线一区二区三区|