zoukankan      html  css  js  c++  java
  • C# 锁与死锁

    什么是死锁:

    所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。如下

    static void LockTooMuch(object lock1, object lock2)
            {
                lock (lock1)  //锁定lock1对象
                {
                    Thread.Sleep(1000); //线程挂起1s
                    lock (lock2) //试图获取lock2对象的锁定
                    {
                        Console.WriteLine("成功获取到lock2对象的锁定");
                    }
                }
            }
    
            /// <summary>
            /// 造成一个死锁
            /// </summary>
            public static void Test()
            {
                //定义两个锁定对象
                object lock1 = new object();
                object lock2 = new object();
    
                //开启线程
                Thread t1 = new Thread(() => {LockTooMuch(lock1,lock2); });
                t1.Start();
    
                //在主线程中锁定lock2对象
                lock (lock2)
                {
                    Console.WriteLine("这将要产生一个死锁");
                    Thread.Sleep(1000);
                    lock (lock1)  //试图访问lock1
                    {
                        Console.WriteLine("成功获取到lock1对象的锁定");
                    }
                }
            }

    通过Monitor的超时锁定机制避免死锁

    直接使用Monitor类。其拥有TryEnter方法,该方法接受一个超时参数。如果在我们能够获取被lock保护的资源之前,超时参数过期,则该方法会返回 false.

    /// <summary>
            /// 使用Monitor避免死锁
            /// </summary>
            public static void Test2()
            {
                //定义两个锁定对象
                object lock1 = new object();
                object lock2 = new object();
    
                //开启线程
                Thread t1 = new Thread(() => {LockTooMuch(lock1,lock2); });
                t1.Start();
    
                //在主线程中使用Monitor类来锁定lock2对象
                //在主线程中锁定lock2对象
                lock (lock2)
                {
                    Console.WriteLine("使用Monitor.TryEnter避免死锁,有一个超时时间的设定 超时返回false");
                    Thread.Sleep(1000);
                    //设置5s的超时时间
                    if(Monitor.TryEnter(lock1,TimeSpan.FromSeconds(5)))
                    {
                        Console.WriteLine("成功获取到lock1对象的锁定");
                    }
                    else
                    {
                        Console.WriteLine("获取lock1对象失败,");
                    }
                }
            }

    if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5))) 这时候是尝试去获取lock1,

    因为lock1倍分支线程给获取了,那么获取不到,这时候等待5秒,5秒后获取不到就直接走了lese这条路,然后就释放了lock2,这时候分支线程就继续运行。

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/netlock/p/14061195.html
Copyright © 2011-2022 走看看