zoukankan      html  css  js  c++  java
  • ConcurrentDictionary 与 Dictionary

    ASP.NET中ConcurrentDictionary是.Net4 增加的,与 Dictionary 最主要区别是, 前者是线程安全的集合,可以由多个线程同时并发读写Key-value。
     
    那么 什么是线程安全?线程安全和非线程安全有什么区别?分别在什么情况下使用?
     
    什么是线程安全 ? 
      线程安全就是指多线程反问时候,采用了加锁机制。
      当线程A访问某个对象时候,采用了保护机制,这时候另一个线程B访问该对象不产生异常。
     
    线程安全和非线程安全有什么区别?
      
      非线程安全是指多线程操作同一个对象可能会出现问题。
      而线程安全则是多线程操作同一个对象不会有问题。 
     
    分别在什么情况下使用?
      当多线程情况下,对 全局变量、静态变量 进行访问或者操作数据的时候, 建议使用线程安全, 非线程安全有几率出现异常。
     
     
    接下来放一个实例:
      分别使用 ConcurrentDictionary  与 Dictionary  根据key读取value, 当key不存在的时候进行写入并读取,key存在的时候直接读取对应的value。
      
      
    1.定一个接口:
      
    public interface IGetLogger
        {
            string GetLogger(string cmdId);
        }

    2. Dictionary 实现:

       public class DictionaryLogger : IGetLogger
        {
            static Dictionary<string, string>  loggreDic = new Dictionary<string, string>();
            public string GetLogger(string cmdId)
            {
                if (!loggreDic.ContainsKey(cmdId))
                {
                    loggreDic.Add(cmdId, $"AAA.{cmdId}");
                }
                return loggreDic[cmdId]; 
            }
        }
    3. ConcurrentDictionary   实现:
      public class ConcurrentDictionaryLogger : IGetLogger
        {
            static ConcurrentDictionary<string, string> loggreDic = new ConcurrentDictionary<string, string>();
    
            public string GetLogger(string cmdId)
            {
                if (!loggreDic.ContainsKey(cmdId))
                {
                    loggreDic.TryAdd(cmdId, $"ConcurrentDictionary.{cmdId}");
                }
                return loggreDic[cmdId];
            } 
        }
    public partial class ConcurrentDictionaryForm : Form
        {
            public ConcurrentDictionaryForm()
            {
                Console.WriteLine("欢迎来到ConcurrentDictionary线程安全");
                InitializeComponent();
            }
    
            /// <summary>
            /// 非线程安全
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Dictionary_Click(object sender, EventArgs e)
            { 
                int threadCount = 5000;
                CountDownLatch latch = new CountDownLatch(threadCount);
                object state = new object();
                for (int i = 0; i < threadCount; i++)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(new WasteTimeDic(latch).DoSth), i);
                }
                latch.Await();
            }
    
            /// <summary>
            /// 线程安全
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ConcurrentDictionary_Click(object sender, EventArgs e)
            {
    
                int threadCount = 5000;
    
                CountDownLatch latch = new CountDownLatch(threadCount);
                object state = new object();
                for (int i = 0; i < threadCount; i++)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(new WasteTime(latch).DoSth), i);
                }
                latch.Await();
    
            }
    
        }
    CountDownLatch 是一个自定义个的并发检测类:
        public class CountDownLatch
        {
            private object lockObj = new Object();
            private int counter;
    
            public CountDownLatch(int counter)
            {
                this.counter = counter;
            }
    
            public void Await()
            {
                lock (lockObj)
                {
                    while (counter > 0)
                    {
                        Monitor.Wait(lockObj);
                    }
                }
            }
    
            public void CountDown()
            {
                lock (lockObj)
                {
                    counter--;
                    Monitor.PulseAll(lockObj);
                }
            }
        }
    
    
      public class WasteTime
        {
            private CountDownLatch latch; 
    
            public WasteTime(CountDownLatch latch)
            {
                this.latch = latch;
            }
    
            public void DoSth(object state)
            {
                //模拟耗时操作  
                //System.Threading.Thread.Sleep(new Random().Next(5) * 1000);
                //Console.WriteLine("state:"+ Convert.ToInt32(state));
    
                IGetLogger conLogger = new ConcurrentDictionaryLogger();
                try
                {
                    Console.WriteLine($"{state}GetLogger:{conLogger.GetLogger("BBB")}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("第{0}个线程出现问题", state));
                }
                //执行完成注意调用CountDown()方法  
                this.latch.CountDown();
            }
    
        }
    
    
        public class WasteTimeDic
        {
            private CountDownLatch latch;
    
            public WasteTimeDic(CountDownLatch latch)
            {
                this.latch = latch;
            }
    
            public void DoSth(object state)
            {
                //模拟耗时操作  
                //System.Threading.Thread.Sleep(new Random().Next(5) * 1000);
                //Console.WriteLine("state:"+ Convert.ToInt32(state));
                IGetLogger conLogger = new DictionaryLogger();
                try
                {
                    Console.WriteLine($"{state}GetLoggerDic:{conLogger.GetLogger("AAA")}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("第{0}个线程出现问题", state));
                }
                //执行完成注意调用CountDown()方法  
                this.latch.CountDown();
            }
    
    
        }
    会有一定几率出现异常情况:
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    iOS中Zbar二维码扫描的使用
    SOJ 1135. 飞跃原野
    SOJ 1048.Inverso
    SOJ 1219. 新红黑树
    SOJ 1171. The Game of Efil
    SOJ 1180. Pasting Strings
    1215. 脱离地牢
    1317. Sudoku
    SOJ 1119. Factstone Benchmark
    soj 1099. Packing Passengers
  • 原文地址:https://www.cnblogs.com/dragon-L/p/8442655.html
Copyright © 2011-2022 走看看