1.11 使用Monitor类锁定资源

  • 本代码演示了一个常见的多线程错误“死锁(deadlock)”。main方法中第一部分演示用Monitor避免死锁,第二部分用lock创建死锁,而死锁后程序会停止工作。
  static void Main(string[] args)
        {
            #region 1.11
            object lock1 = new object();
            object lock2 = new object();
            #region 演示:Monitor避免死锁
            new Thread(() => Class1_11.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");//monitor.tryenter允许不卡住,在经过指定的超时后返回false
                if (Monitor.TryEnter(lock1, 1000))
                {
                    Console.WriteLine("成功获取受保护的资源");
                }
                else
                {
                    Console.WriteLine("获取资源超时!");
                }
            }
            Console.WriteLine("--------");
            #endregion
            #region 演示:lock创建死锁
            new Thread(() => Class1_11.LockTooMuch(lock1, lock2)).Start();
            lock (lock2)
            {
                Console.WriteLine("将发生死锁!");
                Thread.Sleep(1000);
                lock (lock1)
                {
                    Console.WriteLine("成功获取受保护的资源");
                }
            } 
            #endregion
}

  public class Class1_11
    {
        public static void LockTooMuch(object lock1, object lock2)
        {
            lock (lock1)//先锁住第一个对象lock1,过1s后锁住第二个对象lock2.然后在另一个线程
            {
                Thread.Sleep(1000);
                lock (lock2);
            }
        }
    }
  • 代码解读:

LockTooMuch方法:先锁住第一个对象lock1,过1s后锁住第二个对象lock2。然后在另一个线程中启动该方法,尝试在主线程中先后锁第二个和第一个对象。

第二部分用lock关键字的代码,会造成死锁。第一个线程保持对lock1对象的锁定,等待直到lock2对象被释放。主线程保持对lock2的锁定并等待直到lock1释放,但是lock1永远不会被释放。

lock关键字是Monitor类用例的一个语法糖。我们分解使用了lock关键字的代码,会看到如下代码:

bool acquiredLock=false;
try{
	Monitor.Enter(lockObject,ref acquiredLock);
}finally{
	if(acquiredLock)
	{
		Monitor.Exit(lockObject);
	}
}

所以,我们可以直接用Monitor类。它有TryEnter方法,该方法接受一个超时参数。获取资源超时,会返回false。

原文地址:https://www.cnblogs.com/anjun-xy/p/11748113.html