zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    微信支付Native扫码支付模式二之CodeIgniter集成篇
    如何使用硬盘安装debian8.3?
    使用git将代码push到osc上
    树莓派(Raspberry Pi)搭建简单的lamp服务
    win下修改mysql默认的字符集以防止乱码出现
    CodeIgniter2.2.0-在控制器里调用load失败报错的问题
    Ubuntu Server(Ubuntu 14.04 LTS 64位)安装libgdiplus2.10.9出错问题记录
    linux下mono的安装与卸载
    asp.net中ashx生成验证码代码放在Linux(centos)主机上访问时无法显示问题
    使用NPOI将数据导出为word格式里的table
  • 原文地址:https://www.cnblogs.com/anjun-xy/p/11748113.html
Copyright © 2011-2022 走看看