造成死锁

时间:2011-10-20 11:50:04

标签: c# .net multithreading c#-4.0 deadlock

我有一些代码如下所示。这会造成死锁吗?

private readonly object objectLock = new object();

public void MethodA()
{
    lock(objectLock)
    {
       MethodB();
    }
}

public void MethodB()
{
    lock(objectLock)
    {
      //do something
    }
}

更新:将运行2个线程

5 个答案:

答案 0 :(得分:11)

不 - 但这会是:

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个不同的线程),那么你会遇到死锁......

答案 1 :(得分:6)

不,它不是僵局。它在相同的同步对象上锁定相同的线程。线程可以采用嵌套锁。它只需要释放它等于没有。时间。

答案 2 :(得分:3)

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

答案 3 :(得分:3)

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

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

  • 锁定objectLock
  • 致电MethodB
  • 锁定objectLock
  • 解锁objectLock
  • 退出MethodB
  • 解锁objectLock

因此,objectLock被锁定两次并且未触发两次,但没有死锁:

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

答案 4 :(得分:1)

如果您复制粘贴以下行,请编译并运行,以查看控制台中未打印“从未调用”。

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();
    }
}

}