學習筆記-設計模式-創建型模式-單例模式

来源:https://www.cnblogs.com/Andl-Liu/archive/2023/10/09/17751393.html
-Advertisement-
Play Games

單例模式 一個類只有一個實例,並提供一個全局訪問此實例的點,哪怕多線程同時訪問。 單例模式主要解決了一個全局使用的類被頻繁的創建和消費的問題。 單例模式的案例場景 資料庫的連接池不會反覆創建 spring中一個單例模式bean的生成和使用 在我們平常的代碼中需要設置全局的一些屬性保存 七種單例模式的 ...


單例模式

一個類只有一個實例,並提供一個全局訪問此實例的點,哪怕多線程同時訪問。

單例模式主要解決了一個全局使用的類被頻繁的創建和消費的問題。

單例模式的案例場景

  • 資料庫的連接池不會反覆創建
  • spring中一個單例模式bean的生成和使用
  • 在我們平常的代碼中需要設置全局的一些屬性保存

七種單例模式的實現

1.懶漢模式(線程不安全,懶載入)
public static class Singleton_01 {
    private static Singleton_01 instance;
    
    private Singleton_01() {}
    
    public static Singleton_01 getInstance() {
        if (null != instance) {
            return instance;
        }
        instance = new Singleton_01();
        return instance;
    }
}

非常標準且簡單地單例模式。

滿足了懶載入,但是線程不安全。

2.懶漢模式(線程安全,懶載入)
public static class Singleton_02 {
    private static Singleton_02 instance;
    
    private Singleton_02() {}
    
    public static synchronized Singleton_02 getInstance() {
        if (null != instance) {
            return instance;
        }
        instance = new Singleton_02();
        return instance;
    }
}

線程安全,但是效率低,不建議使用。

3.餓漢模式(線程安全)
public class Singleton_03 {
    private static Singleton_03 instance = new Singleton_03();
    
    private Singleton_03() { }
    
    public static Singleton_03 getInstance() {
        return instance;
    }   
}

餓漢模式,在程式啟動的時候直接運行載入。

4.使用內部靜態類(線程安全、懶載入)
public class Singleton_04 {
    private static class SingletonHolder {
        private static Singleton_04 instance = new Singleton_04();
    }
    
    private Singleton_04() { }
    
    public static Singleton_04 getInstance() {
        return SingletonHolder.instance;
    }
}

通過內部靜態類實現了懶載入和線程安全,推薦使用。

5.鎖+雙重校驗(線程安全,懶載入)
private class Singleton_05 {
    private static volatile Singleton_05 instance;
    
    private Singleton_05() { }
    
    public static Singleton_05 getInstance() {
        if (null != instance) {
            return instance;
        }
        synchronized (Singleton_05.class) {
            if (null == instance) {
                instance = new Singleton_05();
            }
        }
        return instance;
    }
}

相較於線程安全的懶漢模式,這種方法效率更高。

6.CAS【AtomicReference】(懶載入,線程安全)
public class Singleton_06 {
    private static final AtomicReference<Singleton_06> INSTANCE = new AtomicReference<Singleton_06>();
    
    private Singleton_06() {  }
    
    public static final Singleton_06 getInstance() {
        for(;;) {
            Singleton_06 instance = INSTANCE.get();
            if (null != instance) {
                return instance;
            }
            INSTANCE.compareAndSet(null, new Singleton_06());
            return INSTANCE.get();
        }
    }
}

AtomicReference<V>可以封裝引用一個V實例,支持併發訪問。

使用CAS的好處就是不需要使用傳統的加鎖方式保證線程安全,而是依賴於CAS的忙等演算法,依賴於底層硬體的實現,來保證線程安全。相對於其他鎖的實現,沒有線程的切換和阻塞,也就沒有了額外的開銷,並且可以遲遲較大的併發性。

但CAS的一個缺點就是忙等,如果一直沒有獲取到將會處於死迴圈中。

7.枚舉單例(線程安全)
public enum Singleton_07 {
    
    INSTANCE;
    
    private Map<String, String> cache = new ConcurrentHashMap<>();

    public Map<String, String> getCache() {
        return cache;
    }

    public void addToCache(String key, String value) {
        cache.put(key, value);
    }
}

《Effective Java》作者推薦使用枚舉的方式解決單例模式,這種方法解決了線程安全、自由串列化和單一實例的問題。

調用時也很方便:Singleton_07.INSTANCE.getCache();

枚舉單例十分簡潔,並且它無常地提供了串列化機制,絕對防止對此實例化(畢竟是枚舉)。

但是它在繼承的場景下是不可使用的,並且不是懶載入(畢竟是枚舉)。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MapReduce服務為用戶提供海量數據的管理及分析功能,快速從結構化和非結構化的海量數據中挖掘您所需要的價值數據。集群中的FusionInsight Manager將提供企業級的集群的統一管理平臺。 ...
  • 最近新項目要上線,考慮成本,放棄雲資料庫,選擇自行安裝,資料庫選擇SQL Server 2022,系統選擇Ubuntu 20.04。 //SQL Server 2022文檔地址 https://learn.microsoft.com/zh-cn/sql/sql-server/?view=sql-se ...
  • 背景 系統需要交付,客戶要求提供交維材料,包括系統的表結構,安排開發人員進行梳理,效率比較慢,遂自己花點時間搗鼓一下,發現有此插件,記錄一下方便與同事分享 前提條件 必須有 go語言環境,有的話直接看第二點 一、安裝 go語言環境 1、檢查本機是否安裝 go go version 2、如果沒有,安裝 ...
  • 一、環境介紹 本文環境,以及本文所採用資料庫為GreatSQL 8.0.32-24 $ cat /etc/system-release Red Hat Enterprise Linux Server release 7.9 (Maipo) $ uname -a Linux gip 3.10.0-11 ...
  • 目錄Vue模板應用{{}} 變數插值v-once 只會插值一次v-html 對HTML代碼插值v-bindHTML標簽屬性的插值在外部傳遞數值類型的數據到組件內部時, 必須使用v-bind指令的方式進行傳遞, 直接使用HTML屬性設置的方式傳遞會將傳遞的數據作為字元串傳遞v-on 監聽、綁定事件v- ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前端換膚方案 - element+less無感換膚(無需頁面刷新) 前言 前不久在改造一個迭代了一年多的項目時,增加了一個換膚功能。通過自己的探索,總結出了一套比較合適的改造方案供大家參考,如有更好的方案歡迎評論區踴躍評論😄 先上效果: ...
  • three.js、webgl、3D煤礦隧道、三維井下人員定位、掘進面三維可視化、縱採面可視化、採集面可視化展示、設備檢測、數字孿生、物聯網3D、3d建築、3d庫房,bim管理系統 ...
  • 導讀 VTable: 不只是高性能的多維數據分析表格,更是行列間創作的方格藝術家! VTable是位元組跳動開源可視化解決方案 VisActor 的組件之一。 在現代應用程式中,表格組件是不可或缺的一部分,它們能夠快速展示大量數據,並提供良好的可視化效果和交互體驗。VTable是一款基於可視化渲染引擎 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...