造成死锁

本文关键字:死锁 | 更新日期: 2023-09-27 18:11:43

我有一些代码,看起来像下面。这会造成死锁吗?

private readonly object objectLock = new object();
public void MethodA()
{
    lock(objectLock)
    {
       MethodB();
    }
}
public void MethodB()
{
    lock(objectLock)
    {
      //do something
    }
}

UPDATE:有2个线程在运行

造成死锁

没有-但这将是:

private readonly object objectLockA = new object();
private readonly object objectLockB = new object();
public void MethodA()
{
    lock(objectLockA)
    {
    lock(objectLockB)
    {
       //...
    }
    }
}
public void MethodB()
{
    lock(objectLockB)
    {
    lock(objectLockA)
    {
      //do something
    }
    }
}

如果你并行调用两个方法(从2个不同的线程),那么你会得到一个死锁…

不,这不是死锁。相同的线程锁定在相同的同步对象上。线程可以使用嵌套锁。它只需要释放它等于no。次。

不,您需要两个锁对象来启用死锁。

如果这是唯一涉及的互斥,它不是。同一个线程可以多次锁定同一个互斥锁,只要它解锁的次数相等。

调用MethodA在同一线程上产生以下操作序列:

  • 锁定objectLock .
  • 呼叫MethodB .
  • 锁定objectLock .
  • 解锁objectLock .
  • 退出MethodB .
  • 解锁objectLock .

因此,objectLock被锁定两次,解锁两次,但没有死锁:

    如果另一个线程试图调用MethodA,它只会阻塞第一个锁,但不会死锁。
  • 如果调用MethodB,同样会发生。
  • 如果第一个线程调用MethodB,然后其他线程调用MethodA,再次发生"正常"阻塞,但不会发生死锁。

如果复制粘贴以下行,编译并运行,看到"never called"没有在控制台中打印。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace deadlocktest
{
    class Program
    {
    static object object1 = new object();
    static object object2 = new object();
    public static void FunctionOne()
    {
        lock (object1)
        {
            Console.WriteLine("FunctionOne called 1");
            Thread.Sleep(1000);
            lock (object2)
            {
                Console.WriteLine("FunctionOne called 2, never called");
            }
        }
    }
    public static void FunctionTwo()
    {
        lock (object2)
        {
            Console.WriteLine("FunctionTwo called 1");
            Thread.Sleep(1000);
            lock (object1)
            {
                Console.WriteLine("FunctionTwo called 2, never called");
            }
        }
    }
    static void Main(string[] args)
    {
        Thread thread1 = new Thread(FunctionOne);
        Thread thread2 = new Thread(FunctionTwo);
        thread1.Start();
        thread2.Start();
        int i = 0;
        while (i < 9)
        {
            Console.WriteLine("How bad thread!");
            i++;
        }
        thread1.Join();
        thread2.Join();
        Console.ReadLine();
    }
}

}