C#多线程编程笔记(1.3)-死锁(Dead Lock)解决方法

近来在学习Eugene Agafonov编写的《C#多线程编程实战》(译),做些笔记也顺便分享一下^-^

using System;
using System.Threading;

namespace 死锁
{
    class Program
    {
        static void Main(string[] args)
        {
            object lock1 = new object();
            object lock2 = new object();

            new Thread(() => LockTooMuch(lock1, lock2)).Start();

            lock (lock2)
            {
                Thread.Sleep(1000);
                Console.WriteLine("Monitor.TryEnter allows not to get stuck,returning false after a specified timeout is elapsed");
                if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5)))
                {
                    Console.WriteLine("Acquired a protected resource succesfully");
                }
                else
                {
                    Console.WriteLine("Timeout acquiring a resource!");
                }
            }
            new Thread(() => LockTooMuch(lock1, lock2)).Start();

            Console.WriteLine("----------------------------------");
            lock (lock2)
            {
                Console.WriteLine("This will be a deadlock!");
                Thread.Sleep(1000);
                lock (lock1)
                {
                    Console.WriteLine("Acquired a protected resource succesfully");
                }
            }

            Console.ReadKey();
        }

        static void LockTooMuch(object lock1,object lock2)
        {
            lock (lock1)
            {
                Thread.Sleep(1000);
                lock (lock2) ;
            }
        }
    }
}

我们先看看LockTooMuch方法。在该方法中我们先锁定了第一个对象,等待一秒后锁定了第二个对象。然后在另一个线程中启动该方法。最后尝试在主线程中先后锁定第二个和第一个对象。如果像该示例的第二部分一样使用lock关键字,将会造成死锁。第一个线程保持对lock1对象的锁定,等待直到lock2对象被释放。主线程保持对lock2对象的锁定并等待直到lock1对象被释放,但lock1对象永远不会被释放,造成了死锁!

死锁是C#中非常有意思也非常头疼的一个现象,不过要避免死锁也不是没有方法的。我们可以直接使用Monitor类,其拥有TryEnter方法,该方法接受一个超时参数。如果在我们能够获取被lock保护的资源之前,超时参数过期,则该方法会返回false。

你可能感兴趣的:(C#-多线程,C#多线程编程笔记)