<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C# 兩大線程本地存儲解決方案:ThreadStatic 與 ThreadLocal

      C# 兩大線程本地存儲解決方案:ThreadStatic 與 ThreadLocal

      一、線程本地存儲

      在 C# 中,static 關(guān)鍵字定義的變量,其作用域是在應(yīng)用程序域(AppDomain)內(nèi)共享的。因此,在多線程操作時,對同一個靜態(tài)變量進行操作可能會導(dǎo)致并發(fā)問題,如鎖競爭等。這種情況下,我們需要一種機制,使某些變量對每個線程獨立,從而避免鎖競爭問題。

      線程本地存儲(Thread-Local Storage,TLS)是一種機制,允許每個線程擁有自己的變量副本。這意味著每個線程對變量的訪問都是獨立的,互不干擾。

      例如,線程安全的 ConcurrentBag 底層的實現(xiàn)就用到了 ThreadLocal 變量,來實現(xiàn)線程間的獨立數(shù)據(jù)存儲。

      二、C# 中的解決方案

      1. ThreadStatic 特性

      概念與用法

      ThreadStatic 是一個用于靜態(tài)字段的特性,可以使字段在每個線程中都有一個獨立的實例。

      示例代碼

      internal class Program
      {
          [ThreadStatic]
          private static int _threadSpecificData = -1;
      
          static void Main(string[] args)
          {
              Task.Run(() =>
              {
                  _threadSpecificData = 1;
                  Console.WriteLine($"第1個線程,線程id: {Environment.CurrentManagedThreadId}: {_threadSpecificData}");
              });
      
              Task.Run(() =>
              {
                  _threadSpecificData = 2;
                  Console.WriteLine($"第2個線程,線程id:{Environment.CurrentManagedThreadId}: {_threadSpecificData}");
              });
      
              Console.ReadKey();
          }
      }
      

      輸出:

      第1個線程,線程id: 9: 1
      第2個線程,線程id:8: 2
      

      注意事項

      只能用于 static 字段。
      每個線程使用變量前,初始化變量。定義變量時,賦值的變量初始值,只會有一個線程的變量有這個初始值,其他線程變量副本是沒有賦值的狀態(tài)。特別主要引用類型的變量,會是null.

      2. ThreadLocal 類

      概念與用法

      ThreadLocal<T> 是 .NET 提供的一個泛型類,用于更靈活地實現(xiàn)線程本地存儲。它允許每個線程擁有獨立的值,并支持通過工廠方法初始化每個線程的值。

      示例代碼

       internal class Program
       {
           static void Main(string[] args)
           {
               ThreadLocal<int> _threadSpecificData = new ThreadLocal<int>(() => Thread.CurrentThread.ManagedThreadId);
      
               Task.Run(() =>
               {
                   Console.WriteLine($"第1個線程,線程id: {Environment.CurrentManagedThreadId}: value: {_threadSpecificData}");
               });
      
               Task.Run(() =>
               {
                   Console.WriteLine($"第1個線程,線程id: {Environment.CurrentManagedThreadId}: value: {_threadSpecificData}");
               });
               Console.ReadKey();
           }
       }
      

      輸出:

      第1個線程,線程id: 8: value: 8
      第1個線程,線程id: 6: value: 6
      

      特點

      支持 Func 委托延遲初始化

      區(qū)別

      特性 ThreadStatic ThreadLocal
      使用范圍 僅用于 static 字段 不限制
      初始化方式 無法直接初始化,需顯式賦值 支持延遲初始化
      管理靈活性 簡單,但功能受限 功能強大,適合復(fù)雜場景

      三、線程本地存儲到底存儲在什么地方

      線程本地存儲的引用地址是存在 TLS(Thread Local Storage)上。
      TLS(Thread Local Storage): 用于存儲線程私有數(shù)據(jù)。
      TEB(Thread Environment Block): 在線程的本地存儲之上,是線程的環(huán)境塊,保存了線程的上下文信息。
      PEB(Process Environment Block): 進程環(huán)境塊,用于存儲進程級的全局信息。

      以下是內(nèi)存結(jié)構(gòu)的示意圖:

      +----------------+
      |   PEB          |
      +----------------+
      |   TEB          | <-- 多個線程
      +----------------+
      |   TLS          |
      +----------------+
      

      四、應(yīng)用場景

      示例 1:用于日志記錄中的線程上下文

      在日志記錄中,通過線程本地存儲可以為每個線程存儲獨立的上下文信息。在多線程應(yīng)用程序中,每個線程可能需要記錄不同級別的日志。使用ThreadLocal可以為每個線程分配一個獨立的日志記錄器實例,從而避免日志記錄的競爭和同步問題。

      internal class Program
      {
          static void Main(string[] args)
          {
              Task.Run(() =>
              {
                  logger.SetContext("線程A");                
                  logger.log("在執(zhí)行第1步操作");
                  Thread.Sleep(200);
                  logger.log("在執(zhí)行第2步操作");
                  logger.log("執(zhí)行完了");
              });
      
              Task.Run(() =>
              {
                  logger.SetContext("線程B");
                  logger.log("在執(zhí)行第1步操作");
                  logger.log("遇到異常,退出了");
              });
              Console.ReadKey();
          }
      }
      
      class logger
      {
          private static ThreadLocal<string> _context = new ThreadLocal<string>();
      
          public static void SetContext(string context)
          {
              _context.Value = context;
          }
      
          public static void log(string message)
          {
              Console.WriteLine($"[{_context.Value}]{message}");
          }
      }
      

      輸出:

      [線程A]在執(zhí)行第1步操作
      [線程B]在執(zhí)行第1步操作
      [線程B]遇到異常,退出了
      [線程A]在執(zhí)行第2步操作
      [線程A]執(zhí)行完了
      

      五、總結(jié)

      C# 提供了兩種線程本地存儲解決方案:
      ThreadStatic:簡單直接,但初始化靈活性較差。
      ThreadLocal:功能強大,適合更復(fù)雜的場景。

      根據(jù)具體應(yīng)用場景選擇合適的方案,可以顯著提高程序的性能和線程安全性。

      posted @ 2025-01-10 20:31  dotNet編程拾光  閱讀(186)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美人成网站在线观看看| 色狠狠色婷婷丁香五月| 国产精品亚洲综合久久小说| 中文字幕人妻中文AV不卡专区| 波多野结衣无内裤护士 | 视频二区国产精品职场同事| 奉化市| 亚洲国产在一区二区三区| 免费观看欧美猛交视频黑人| 国内精品伊人久久久久av| 国产精品中文字幕一区| 日本一区二区精品色超碰| 欧美一本大道香蕉综合视频| 人体内射精一区二区三区| 亚洲国产综合精品2020| 国产精品播放一区二区三区 | 色爱综合激情五月激情| 人妻体内射精一区二区三四| 五级黄高潮片90分钟视频 | 亚洲一区二区无码影院| 91午夜福利在线观看精品| 无卡无码无免费毛片| 国产日韩一区二区四季| 国产精品三级黄色小视频| 97se综合| 久久中精品中文字幕入口| 国产一区二区黄色在线观看| 国产稚嫩高中生呻吟激情在线视频| 亚洲深深色噜噜狠狠网站| 国产激情一区二区三区成人| 成年无码av片在线蜜芽| 蜜桃av无码免费看永久| 少妇人妻偷人精品一区二| 亚洲第一无码AV无码专区| 亚洲中文字字幕精品乱码| 亚洲大尺度视频在线播放| 无码尹人久久相蕉无码| 亚洲国产日韩一区三区| 亚洲欧美日韩成人综合一区| 国产乱码一区二区三区| 永久免费的av在线电影网|