C# 制造僵局

C# 制造僵局,c#,.net,multithreading,c#-4.0,deadlock,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 } } 更新:将有两个线程运行否,您需要两个锁对

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

private readonly object objectLock = new object();

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

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

更新:将有两个线程运行

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

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

否-但这将是:

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
    }
    }
}

如果并行调用这两个方法(从两个不同的线程),则会出现死锁…

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

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

  • 锁定
    objectLock
  • 调用
    MethodB
  • 锁定
    objectLock
  • 解锁
    objectLock
  • 退出
    方法b
  • 解锁
    objectLock
因此,
objectLock
被锁定两次,被解除锁定两次,但没有死锁:

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

如果复制粘贴以下行,请编译并运行,以确保控制台中不会打印“从未调用”

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();
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
名称空间死锁测试
{
班级计划
{
静态对象object1=新对象();
静态对象object2=新对象();
公共静态void FunctionOne()
{
锁(对象1)
{
Console.WriteLine(“FunctionOne称为1”);
睡眠(1000);
锁(对象2)
{
WriteLine(“FunctionOne调用了2,从未调用”);
}
}
}
公共静态无效函数二()
{
锁(对象2)
{
Console.WriteLine(“FunctionTwo称为1”);
睡眠(1000);
锁(对象1)
{
WriteLine(“FunctionTwo调用2,从未调用”);
}
}
}
静态void Main(字符串[]参数)
{
螺纹1=新螺纹(功能一);
螺纹2=新螺纹(功能二);
thread1.Start();
thread2.Start();
int i=0;
而(i<9)
{
控制台。WriteLine(“多么糟糕的线程!”);
i++;
}
thread1.Join();
螺纹2.连接();
Console.ReadLine();
}
}

}

如果MethodA调用MethodB两次会怎么样。那还可以吗?是的,还可以。你试过了吗?死锁将挂起死锁中涉及的所有线程。单线程不能出现死锁。你的应用程序中有多个线程吗?@Jon即使这样,也不会导致死锁。他们锁定的是同一个同步对象。谢谢你的帮助。很appreciated@Jon:
MethodB
当然是由同一线程中的
MethodA
调用的。仍然没有僵局。