保证集合的线程安全问题

确保集合的线程安全。在开启多线程操作集合的时候,很容易对集合进行增删改查,这样子,集合的访问情况就会变化。

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();
        }
    }
复制代码

 

posted @   Wen_Chen  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示