zoukankan      html  css  js  c++  java
  • C# 避免死锁,使用Monitor.TryEnter方法设定超时时间

    1.在多任务系统下,当一个或多个进程等待系统资源,而资源又被进程本身或其它进程占用时,就形成了死锁。总的来说,就是两个线程,都需要获取对方锁占有的锁,才能够接着往下执行,但是这两个线程互不相让,你等我先释放,我也等你先释放,但谁都不肯先放,就一直在这僵持住了。

    2.死锁演示:

     1         static void Main(string[] args)
     2         {
     3             Task.Run(()=> Method1());
     4             Task.Run(() => Method2());
     5             Console.Read();
     6         }
     7         static void Method1()
     8         {
     9             lock (obj1)
    10             {
    11                 Console.WriteLine("开始执行方法一");
    12                 Thread.Sleep(1000);
    13                 lock (obj2)
    14                 {
    15                     Console.WriteLine("方法一执行完毕");
    16                 }
    17             }
    18         }
    19         static void Method2()
    20         {
    21             lock (obj2)
    22             {
    23                 Console.WriteLine("开始执行方法二");
    24                 Thread.Sleep(1000);
    25                 lock (obj1)
    26                 {
    27                     Console.WriteLine("方法二执行完毕");
    28                 }
    29             }
    30         }

    结果如下,这两个方法永远都不会执行完毕。

    3.那么,死锁应该怎么样解决呢?

    • 首先,应该尽量避免大量嵌套的锁的使用,这也是预防为主,当然也有信号量也可能会造成死锁,这样的话只能靠程序员自身注意去避免了。
    • 如果需要使用嵌套锁,可以使用锁的超时机制来避免对资源的长时间占用,演示如下:
       1         private static readonly object obj1 = new object();
       2         private static readonly object obj2 = new object();
       3         static void Main(string[] args)
       4         {
       5             Task.Run(()=> Method1());
       6             Task.Run(() => Method2());
       7             Console.Read();
       8         }
       9         static void Method1()
      10         {
      11             try
      12             {
      13                 if (Monitor.TryEnter(obj1, 5000))
      14                 {
      15                     Console.WriteLine("开始执行方法一");
      16                     Thread.Sleep(1000);
      17                     bool locked = false;
      18                     try
      19                     {
      20                         Monitor.TryEnter(obj2, 5000, ref locked);
      21                         Console.WriteLine("方法一执行完毕");
      22                     }
      23                     finally
      24                     {
      25                         if (locked)
      26                         {
      27                             Monitor.Exit(obj2);
      28                         }
      29                     }
      30                 }
      31             }
      32            finally
      33             {
      34                 Monitor.Exit(obj1);
      35             }
      36         }
      37         static void Method2()
      38         {
      39             try
      40             {
      41                 if (Monitor.TryEnter(obj2, 5000))
      42                 {
      43                     Console.WriteLine("开始执行方法二");
      44                     Thread.Sleep(1000);
      45                     bool locked=false;
      46                     try
      47                     {
      48                         Monitor.TryEnter(obj1, 5000,ref locked);
      49                         Console.WriteLine("方法二执行完毕");
      50                     }
      51                     finally
      52                     {
      53                         if (locked)
      54                         {
      55                             Monitor.Exit(obj1);
      56                         }
      57                     }
      58                 }
      59             }
      60             finally
      61             {
      62                 Monitor.Exit(obj2);
      63             }
      64         }

       这样,即使在两个线程都在互相等待资源的情况下,利用超时机制,依然能够使他们放弃当前锁,保证解决死锁问题。

    本文来自博客园,作者:云辰,转载请注明原文链接:https://www.cnblogs.com/yunchen/p/14900265.html

  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/yunchen/p/14900265.html
Copyright © 2011-2022 走看看