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

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

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

      多線程環(huán)境下非安全Dictionary引起的“已添加了具有相同鍵的項”問題

      問題:

      代碼是在多線程環(huán)境下,做了簡單的Key是否存的判斷, 測試代碼如下:

      public class Program
          {
              static Dictionary<string, Logger> loggreDic;
              static object loggerDicLocker = new object();
              public static void Main()
              {
                  loggreDic = new Dictionary<string, Logger>();
                  for (int i = 0; i < 100; i++)
                  {
                      ThreadPool.QueueUserWorkItem(o =>
                      {
                          try
                          {
                              var logger = GetLogger("AAA");
                          }
                          catch (Exception)
                          {
                              Console.WriteLine(string.Format("弟{0}個線程出現(xiàn)問題", o));
                          }
      
                      }, i);
                  }
                  Console.ReadKey();
              }
      
              static Logger GetLogger(string cmdId)
              {
                  if (!loggreDic.ContainsKey(cmdId))
                  {
                      loggreDic.Add(cmdId, LogManager.GetLogger(string.Format("ChinaPnrApi.{0}", cmdId)));
                  }
                  return loggreDic[cmdId];
              }
          }

      可以看到在GetLogger的地方做了判斷的處理,但是在多線程的時候還是會出現(xiàn)在取的時候取不到的問題。可以參考下面截圖 :

      image

      從錯誤異常很容易判斷,是在Dictionary中加了重復(fù)的Key造成的.

      所以總體上來看這段代碼所犯的問題是不是線程安全的代碼.

       

      解決方案 :

      1. 使用Locker解決

      2. 使用線程安全的

      下面對兩種方式都做了實現(xiàn):

      public interface IGetLogger
          {
              Logger GetLogger(string cmdId);
          }
      
          public class ConcurrentDictionaryLogger : IGetLogger
          {
              ConcurrentDictionary<string, Logger> loggreDic = new ConcurrentDictionary<string, Logger>();
              public Logger GetLogger(string cmdId)
              {
                  if (!loggreDic.ContainsKey(cmdId))
                  {
                      loggreDic.TryAdd(cmdId, LogManager.GetLogger(string.Format("ChinaPnrApi.{0}", cmdId)));
                  }
                  return loggreDic[cmdId];
              }
          }
      
          public class LockerDictionaryLogger : IGetLogger
          {
              Dictionary<string, Logger> loggreDic = new Dictionary<string, Logger>();
              object locker = new object();
              public Logger GetLogger(string cmdId)
              {
                  if (!loggreDic.ContainsKey(cmdId))
                  {
                      lock (locker)
                      {
                          if (!loggreDic.ContainsKey(cmdId))
                          {
                              loggreDic.Add(cmdId, LogManager.GetLogger(string.Format("ChinaPnrApi.{0}", cmdId)));
                          }
                      }
                  }
                  return loggreDic[cmdId];
              }
          }

      測試代碼如下:

      public static void Main()
              {
                  IGetLogger conLogger = new ConcurrentDictionaryLogger();
      
                  IGetLogger lockerLogger = new LockerDictionaryLogger();
      
                  CodeTimer.Time("使用ConcurrentDictionary", 1000000, () =>
                  {
                      ThreadPool.QueueUserWorkItem(o =>
                      {
                          try
                          {
                              var logger = conLogger.GetLogger("AAA");
                              if (logger == null)
                              {
                                  Console.WriteLine(string.Format("弟{0}個線程獲取到的值是 NULL", o));
                              }
                          }
                          catch (Exception ex)
                          {
                              Console.WriteLine(string.Format("弟{0}個線程出現(xiàn)問題, {1}", o, ex.Message));
                          }
                      });
                  });
      
                  CodeTimer.Time("使用LockDictionary", 1000000, () =>
                  {
                      ThreadPool.QueueUserWorkItem(o =>
                      {
                          try
                          {
                              var logger = conLogger.GetLogger("AAA");
                              if (logger == null)
                              {
                                  Console.WriteLine(string.Format("弟{0}個線程獲取到的值是 NULL", o));
                              }
                          }
                          catch (Exception ex)
                          {
                              Console.WriteLine(string.Format("弟{0}個線程出現(xiàn)問題, {1}", o, ex.Message));
                          }
                      });
                  });
      
                  Console.WriteLine("已執(zhí)行完成");
                  Console.ReadKey();
              }

      用Release模式編譯之后,測試的結(jié)果:

      第一次:

      image

      第二次:

      image

      第三次:

      image

      總結(jié):

      從測試結(jié)果來看,都解決了我們上述的問題,總體的時間比值來看ConcurrentDictionary稍微優(yōu)于LockDictionary, 但是差別不是很大, 第一次幾乎持平.

      寫代碼還是要多注意線程安全的問題。

       

      上面的CodeTimer用的是: http://www.rzrgm.cn/JeffreyZhao/archive/2009/03/10/codetimer.html

      posted @ 2015-10-03 19:01  DukeCheng  閱讀(919)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲人成人伊人成综合网无码| 免费人成再在线观看网站| 狠狠色噜噜狠狠狠狠2021| 天堂影院一区二区三区四区| 亚洲区日韩精品中文字幕| 免费观看在线A级毛片| 国产精品女视频一区二区| 思思热在线视频精品| 这里只有精品在线播放 | 日韩精品一二三黄色一级| 亚洲欧美色综合影院| 天堂网av一区二区三区| 巩义市| 素人视频亚洲十一十二区| 久久精品久久电影免费理论片| 亚洲精品在线二区三区| 国产亚洲精品久久综合阿香| 色视频在线观看免费视频| 日韩深夜福利视频在线观看| 免费人成年激情视频在线观看| 国产粉嫩学生高清专区麻豆 | 国产欧美日韩综合精品二区 | 欧美成人一区二区三区不卡| 国产乱妇无码大片在线观看| 国产剧情视频一区二区麻豆| 久久综合久中文字幕青草| 亚洲人成电影网站色mp4| 亚洲中文字幕国产综合| 国产成人高清亚洲综合| 乱人伦中文字幕成人网站在线| 性xxxx搡xxxxx搡欧美| 伊人欧美在线| 亚洲熟女乱色综合亚洲图片| 乌兰浩特市| 办公室强奷漂亮少妇同事| 最新亚洲精品国偷自产在线| 亚洲国产成人字幕久久| 亚洲欧美日韩久久一区二区| 国产亚洲一区二区三区av| 久久99九九精品久久久久蜜桃| 亚洲熟妇色自偷自拍另类|