C# 多线程死锁及Monitor.TryEnter方法

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值