保证集合的线程安全问题
确保集合的线程安全。在开启多线程操作集合的时候,很容易对集合进行增删改查,这样子,集合的访问情况就会变化。
AutoResetEvent:reset()方法.将线程设置为非终止状态,导致线程阻止;set()方法.将线程设置为终止状态,允许一个或多个等待线程继续。两者设置成功均返回true,不成功返回false.
waitOn():阻止当前线程,直到接收到信号。收到set信号后,只执行一个线程,其他继续等待。
static List<Person> personList = new List<Person>() { new Person{Name = "Samliy",Age = 29}, new Person{Name = "Jimmy",Age = 31}, new Person{Name = "Machial",Age = 28} }; static AutoResetEvent auto = new AutoResetEvent(false); static void Main(string[] args) { Console.WriteLine("Hello World!"); Thread thread01 = new Thread(() => { auto.WaitOne(); //foreach (var a in personList) //{ // Console.WriteLine(a.ToString()); // Thread.Sleep(1000); //}
//这里如果换成for循环,则不会报错,如果用foreach则会报错,因为集合修改,foreach会有版本号的判断导致无法遍历
for (int i = 0; i < personList.Count; i++) { Console.WriteLine(personList[i].ToString()); Thread.Sleep(1000); } }); thread01.Start(); Thread thread02 = new Thread(() => { auto.Set(); Thread.Sleep(1000); personList.RemoveAt(2); }); thread02.Start(); }
在泛型集合出现之前,非泛型集合一般会采用SyncRoot属性,要保证非泛型集合的线程安全,就得锁住这个属性来实现
但是泛型集合是没有这个属性的,要通过创建一个锁定对象来完成同步任务。
class Program { static List<Person> personList = new List<Person>() { new Person{Name = "Samliy",Age = 29}, new Person{Name = "Jimmy",Age = 31}, new Person{Name = "Machial",Age = 28} };static AutoResetEvent auto = new AutoResetEvent(false); static Object sync = new object(); static void Main(string[] args) { //Object sync = new object(); Console.WriteLine("Hello World!"); Thread thread01 = new Thread(() => { auto.WaitOne(); lock (sync) { Console.WriteLine("先打印数据"); foreach (var a in personArrayList) { Console.WriteLine(a.ToString()); Thread.Sleep(1000); } } //for (int i = 0; i < personList.Count; i++) //{ // Console.WriteLine(personList[i].ToString()); // Thread.Sleep(1000); //} }); thread01.Start(); Thread thread02 = new Thread(() => { auto.Set(); lock (sync) { Console.WriteLine("先删除数据"); Thread.Sleep(1000); personArrayList.RemoveAt(2); } }); thread02.Start(); } }
使用非泛型的线程锁:
非泛型的集合,提供SyncRoot的锁方法,可以锁住集合只让一个线程操作。
class Program { static List<Person> personList = new List<Person>() { new Person{Name = "Samliy",Age = 29}, new Person{Name = "Jimmy",Age = 31}, new Person{Name = "Machial",Age = 28} }; static ArrayList personArrayList = new ArrayList() { new Person{Name = "Samliy",Age = 29}, new Person{Name = "Jimmy",Age = 31}, new Person{Name = "Machial",Age = 28} }; static AutoResetEvent auto = new AutoResetEvent(false); //static Object sync = new object(); static void Main(string[] args) { //Object sync = new object(); Console.WriteLine("Hello World!"); Thread thread01 = new Thread(() => { auto.WaitOne(); lock (personArrayList.SyncRoot) { Console.WriteLine("先打印数据"); foreach (var a in personArrayList) { Console.WriteLine(a.ToString()); Thread.Sleep(1000); } } //for (int i = 0; i < personList.Count; i++) //{ // Console.WriteLine(personList[i].ToString()); // Thread.Sleep(1000); //} }); thread01.Start(); Thread thread02 = new Thread(() => { auto.Set(); lock (personArrayList.SyncRoot) { Console.WriteLine("先删除数据"); Thread.Sleep(1000); personArrayList.RemoveAt(2); } }); thread02.Start(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】