C# 在两个不同的方法里面Lock同一个锁对象,是否需要线程等待?

来源:互联网 发布:电子图书阅读软件 编辑:程序博客网 时间:2024/06/11 17:04

前述:

C#中支持多线程,而多线程引发的一个比较突出的问题就是在同一个时间里,可能会有多个线程访问同一个资源,引起资源的竞争

导致数据损坏。

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的

很多时候,我们在使用Lock关键字,其锁住的不是多个线程里真正要竞争的资源,而是通过创建一个与竞争资源“随行”的锁对象,对它进行加锁,“随行”即这个锁对象在每次访问竞争资源时,都要先加锁它。

如:  

static void Main(string[] args)        {             ls.Add(1);            ls.Add(2);            Thread td1 = new Thread(new ThreadStart(Test1));            td1.Start();            Thread td2 = new Thread(new ThreadStart(Test2));            td2.Start();            Console.ReadLine();        }        private static object olock = new object();//随行的所对象        private static List<long> ls = new List<long>();//真正竞争的资源        private static void Test1()        {            lock (olock)            {                Console.WriteLine("方法1开始" + DateTime.Now.ToString());                Thread.Sleep(10000);                ls.Add(1);                Console.WriteLine("方法1结束" + DateTime.Now.ToString());            }        }        private static void Test2()        {            lock (olock)            {                Console.WriteLine("方法2开始" + DateTime.Now.ToString());                foreach (long i in ls)                {                    Console.WriteLine(i);                }                Console.WriteLine("方法2结束" + DateTime.Now.ToString());            }        }

上面代码中,两个线程真正竞争的资源是ls,两个方法里面都会访问ls,我却加一个随行的锁对象olock,在每次操作ls时,都对它进行加锁。
在使用lock关键字时,我突然想到“在两个不同的方法里面Lock同一个锁对象,是否需要线程等待?”这问题,之后我用上面的测试代码验证了其结果。

  在Test1()方法中,我把线程1先挂起10秒,来验证线程2运行的Test2()方法是否需要等待10秒才运行。


结果显示:线程2的Test2()方法需要等待10秒才运行。

大家也可以试试,如果不加lock关键字,会出现什么结果?

原创粉丝点击