阅读量:0
1、非线程安全举例
Dictionary<int, int> dic = new Dictionary<int, int>(); private void TestAddNotSafe1() { while (true) { for (int i = 0; i < 1000000; i++) { if (dic.ContainsKey(i) == false) { dic.Add(i, i); } Thread.Sleep(1); } break; } } private void TestAddNotSafe2() { while (true) { for (int i = 0; i < 1000000; i++) { if (dic.ContainsKey(i) == false) { dic.Add(i, i); } Thread.Sleep(1); } break; } }
Task.Run(TestAddNotSafe1); Task.Run(TestAddNotSafe2);
上述代码运行后报错,如下:
这是当前线程判断没有该键,准备添加键值对的时候,另一个线程已经添加了该键,所以提示已经添加了相同的项。
2、线程安全举例
为了解决上面的问题,需要使用一个线程安全的字典,
ConcurrentDictionary<int, int> concurrentDictionary = new ConcurrentDictionary<int, int>(); private void TestAddSafe1() { while (true) { for (int i = 0; i < 1000000; i++) { if (concurrentDictionary.ContainsKey(i) == false) { if (concurrentDictionary.TryAdd(i, i)) { } else { MessageBox.Show("错误1"); } } Thread.Sleep(1); } break; } } private void TestAddSafe2() { while (true) { for (int i = 0; i < 1000000; i++) { if (concurrentDictionary.ContainsKey(i) == false) { if (concurrentDictionary.TryAdd(i, i)) { } else { MessageBox.Show("错误2"); } } Thread.Sleep(1); } break; } }
Task.Run(TestAddSafe1); Task.Run(TestAddSafe2);
运行后弹出窗体,提示“错误1”或者“错误2”,但是软件没有崩溃,这是因为TryAdd方法调用返回了false,所以线程安全字典的好处是不会导致软件崩溃,添加值失败只会返回false而已。
总结:
对于字典的线程安全问题,除了TryAdd方法外还有TryRemove、TryUpdate方法。