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(); //先锁定对象1,后锁定对象2
lock (lock2) //先锁定对象2,然后请求锁1,请求超时返回false,锁2释放,未造成死锁
{
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(); //先 锁1 再锁2
Console.WriteLine("----------------------------------");
lock (lock2) //请求锁2,后请求锁1超时,造成死锁
{
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。
原文:https://blog.csdn.net/qq_35445058/article/details/80704722