首页 > 其他 > 详细

1.11 使用Monitor类锁定资源

时间:2019-10-27 17:39:15      阅读:120      评论:0      收藏:0      [点我收藏+]
  • 本代码演示了一个常见的多线程错误“死锁(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。

1.11 使用Monitor类锁定资源

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!