博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 在多线程环境中,进行安全遍历操作
阅读量:6912 次
发布时间:2019-06-27

本文共 1844 字,大约阅读时间需要 6 分钟。

本文以List作为操作对象

MSDN官方给出的List的线程安全的说法:
此类型的公共静态成员是线程安全的。但不能保证任何实例成员是线程安全的。
只要不修改该集合,List 就可以同时支持多个阅读器。通过集合枚举在本质上不是一个线程安全的过程。在枚举与一个或多个写访问竞争的罕见情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合。若要允许多个线程访问集合以进行读写操作,则必须实现自己的同步。
如果不进行同步操作?
假如一个线程进行删除操作,一个线程进行遍历操作,那么在遍历过程中,集合被修改,会导致出现InvalidOperationException的异常,提示:集合已修改;可能无法执行枚举操作。
如何同步,保证遍历的安全
这里使用了临界区,互斥锁来保证线程遍历过程的安全,示例代码如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Threading; 4  5 namespace ConsoleApp 6 { 7     class Program 8     { 9         public static List
simpleList = new List
();10 11 public static void Main(string[] args)12 {13 // 临界区对象14 object lockObj = new object();15 16 // 向List中添加测试数据17 string[] data = { "1", "2", "3", "4", "5", "6", "7", "8" };18 simpleList.AddRange(data);19 // 此线程用于遍历数组20 new Thread(new ThreadStart(() =>21 {22 // 用于同步,进入临界区,只有遍历完,释放临界区对象的互斥锁,才能进行写操作23 lock (lockObj)24 {25 foreach (var item in simpleList)26 {27 Console.WriteLine(item);28 Thread.Sleep(500);29 }30 }31 })).Start();32 // 此线程执行删除操作33 new Thread(new ThreadStart(() =>34 {35 lock (lockObj)36 {37 simpleList.RemoveAt(0);38 Console.WriteLine("rm 1");39 Thread.Sleep(500);40 simpleList.RemoveAt(0);41 Console.WriteLine("rm 2");42 }43 })).Start();44 45 Console.ReadLine();46 }47 }48 }

 

转载于:https://www.cnblogs.com/testsec/p/6095984.html

你可能感兴趣的文章
js的类型转换
查看>>
FortiGate下视频会议等语音相关配置
查看>>
ERP按序打印问题
查看>>
文件的IO(输入/输出) 和 文件系统
查看>>
线程安全的小例子
查看>>
Android入门(八)广播
查看>>
Java锁--非公平锁
查看>>
java开始到熟悉61
查看>>
表示层设计模式:Intercepting Filter(截取筛选器)模式
查看>>
设计模式 之 《外观模式》
查看>>
淘宝初始化代码 - 解决浏览器的兼容问题
查看>>
xcode5修改APP名字
查看>>
Python 元组
查看>>
36.CSS3多列布局
查看>>
Spark的动态资源分配
查看>>
解决类似 /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found 的问题
查看>>
robotframwork的WEB功能测试(一)—切换window窗口
查看>>
云时代架构读后感12--架构师是怎样炼成的
查看>>
js事件中绑定另一事件导致事件多次执行
查看>>
堆与栈
查看>>