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。

  • 相关阅读:
    关于cmake、make、make install
    windows开启ip_forwarding功能
    最新devstack安装(ussuri)
    【rabbitmq】之业务封装
    【rabbitmq】之过期和死信队列
    【rabbitmq】之confirm和return机制
    【rabbitmq】之消费端手动ack
    java短网址服务
    详解druid打印SQL日志
    logback配置文件拆分,抽取公共配置
  • 原文地址:https://www.cnblogs.com/anjun-xy/p/11748113.html
Copyright © 2011-2022 走看看