單例模式,多線程單例,雙重鎖定單例,工廠單例創建上下文。

来源:http://www.cnblogs.com/fighting2014/archive/2017/07/12/7153362.html
-Advertisement-
Play Games

單例子模式定義 保證一個類僅有一個實例,並提供一個訪問它的全局訪問點. 通常我們可以讓一個全局變數使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法就是讓類自身負責保存它的唯一實例。這個類可以保證沒有其它實例可以唄創建並且它可以提供一個訪問該實例的方法,這就是單例模式。 單例子模式簡單 ...


單例子模式定義

  保證一個類僅有一個實例,並提供一個訪問它的全局訪問點.

通常我們可以讓一個全局變數使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法就是讓類自身負責保存它的唯一實例。這個類可以保證沒有其它實例可以唄創建並且它可以提供一個訪問該實例的方法,這就是單例模式。

 

單例子模式簡單實現

     Singleton類定義了一個GetInstance 操作,允許客戶訪問它的唯一實例,GetInstance是一個靜態方法,主要負責創建自己的唯一實例。

  public class Singleton
    {
        private static Singleton _instance;

        private Singleton()//私有化構造函數,阻止外界利用new關鍵詞來創建實例
        {}

        public static Singleton GetInstance()
        {
            return _instance ?? (_instance = new Singleton());
        }
    }
    測試代碼
 public void Myaction()
        {
            var s1 = Singleton.GetInstance();
            var s2 = Singleton.GetInstance();
            if (s1 == s2)
            {
                Console.WriteLine("兩個對象是相同的!");
            }
            Console.Read();
        }

 

多線程時的單例

 上面的代碼在多線程的程式下運行明細是有問題的,當多個線程同時訪問Singleton類 都調用GetInstance()方法,就有可能會創建多個實例。

 這種情況我們可以給進程一把鎖來處理,這裡需要理解 lock 語句的涵義,lock 是確保當前一個線程位於代碼的臨界區時,另一個線程不進入臨界區。如果其它線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。

簡單實現
 public class Singleton
    {
        private static Singleton _instance;
        //程式執行時創建一個靜態的只讀的進程輔助對象
        private static readonly object SyncRoot = new object();

        private Singleton()//私有化構造函數,阻止外界利用new關鍵詞來創建實例
        { }
        
        public static Singleton GetInstance()
        {
            lock (SyncRoot)//在同一時刻加了鎖的那部分程式只有一個線程可以進入
            {
                _instance= _instance ?? (_instance = new Singleton());
            }
            return _instance;
        }
    }

 

雙重鎖定(Double-Check Locking)

 通過上面的例子我們不難發現當我們每次調用 GetInstance() 方法時都要 lock 這種做法顯然是影響性能的所以我們需要再加一層判斷

   簡單實現
public class Singleton
    {
        private static Singleton _instance;
        //程式執行時創建一個靜態的只讀的進程輔助對象
        private static readonly object SyncRoot = new object();
        private Singleton()//私有化構造函數,阻止外界利用new關鍵詞來創建實例
        {}

        public static Singleton GetInstance()
        {
            if (_instance == null)//先判斷實例是否存在,不存在在枷鎖處理
            {
                lock (SyncRoot)//在同一時刻加了鎖的那部分程式只有一個線程可以進入
                {
                    _instance = _instance ?? (_instance = new Singleton());
                }
            }
            return _instance;
        }
    }

 

 

工廠單例創建數據上下文

 我們在開發過程中經常都需要對數據上下文進行單例,所以這裡結合簡單工廠 來實現數據上下文的創建

簡單實現
public  class DbFactory
    {
        private static readonly object SyncRoot=new object();
        private DbFactory()
        {}
        #region 獲取當前的上下文對象
        /// <summary>
        /// 單例工廠 獲取當前的上下文對象  //考慮多線程情況
        /// </summary>
        /// <returns></returns>
        public static  SiyoukuContext GetCurrentDbContext()
        {
            var context = (SiyoukuContext) CallContext.GetData("DbContext"); //從數據槽獲取
            if (context == null)
            {
                lock (SyncRoot)//雙重鎖定
                {
                    if (context == null)
                    {
                        //如果不存在 ,則實例化一個上下文對象
                        context = new SiyoukuContext();
                        CallContext.SetData("DbContext", context);
                    }
                }
            }
            return context;
        }

        #endregion
    }

 

 

本文記錄了自己對單例模式的總結

博主網址:http://www.siyouku.cn

本文永久更細地址:http://siyouku.cn/article/6812.html


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

-Advertisement-
Play Games
更多相關文章
  • 系列關聯文章 系列關聯文章 此系列文章歸屬於:ASP.NET MVC+Bootstrap+JQuery+SqlServer,其他幾篇文章請參照如下: 詳解google Chrome瀏覽器(理論篇) 詳解Google Chrome瀏覽器(操作篇)(上) 詳解Google Chrome瀏覽器(操作篇)( ...
  • 原理:利用mysql二進位日誌文件,實現數據同步 步驟: 一、配置主庫(Master) 1. 修改主庫my.cnf配置文件,加入如下配置 [root@localhost ~]# nano -w /etc/my.cnf [mysqld] log-bin=mysql-bin server-id=1 2. ...
  • 本文所選的例子來自於《Advanced Bash-scripting Gudie》一書,譯者 楊春敏 黃毅 -a 和 -o一般與[ ]使用,如:[ "$exp1" -a "$exp2" ] && 和 || 一般與[[ ]] 使用,如:[[ condition1 && condition2 ]] 以上 ...
  • linux系統是多用戶(Multi-users)和多任務(Multi-tasks)的,這樣的目的是為了一臺linux主機可以給很多用戶提供服務同時運行多種服務,但是我們是怎麼區分每個用戶呢?作為一個管理員我對linux系統許可權有哪些?作為一個普通的用戶又可以對linux系統有哪些操作呢?這裡就牽扯到 ...
  • 本文所選的例子來自於《Advanced Bash-scripting Gudie》一書,譯者 楊春敏 黃毅 腳本運行結果 ...
  • 關於圖形界面的配置,我這裡就不多介紹了,這個很簡單。這裡介紹的是如何通過修改配置文件來實現虛擬網卡。 首先介紹ubuntu(我這裡使用的是ubuntu-16.04)下虛擬網卡的配置 1、先用ifconfig查看當前的網卡配置 一般沒有進行設置之前,列印的信息如上所示。 2、查看當前網卡配置,打開配置 ...
  • using System.Collections.Generic;//引用命名空間//Dictionary可以理解為散列集合 public class DictionaryTest { public static void Main() { //1.初始化 Dictionary dicA = new... ...
  • -> List<T> 線性集合,長度可變的數組 -> 增 Add() AddRange() Insert() 添加一個元素list.Add("張三"); 添加一組元素 string[] temArr={"張三","李四","王五"}; list.AddRange(temArr); 插入一個元素 li ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...