我想我在这里遗漏了一些明显的东西:

为什么此代码不会导致死锁:

static void Main(string[] args)
{
    object _lock1 = new object();
    object _lock2 = new object();

    Thread code1 = new Thread(() =>
    {
        lock (_lock1)
        {
            lock (_lock2)
            {
                Console.WriteLine("A");
                Thread.Sleep(3000);
            }
        }
    });

    Thread code2 = new Thread(() =>
    {
        lock (_lock2)
        {
            lock (_lock1)
            {
                Console.WriteLine("B");
                Thread.Sleep(3000);
            }
        }
    });

    code1.Start();
    code2.Start();

    code1.Join();
    code2.Join();

    Console.WriteLine("Done");
}

但这确实做到了:
static void Main(string[] args)
{
    object _lock1 = new object();
    object _lock2 = new object();

    Thread code1 = new Thread(() =>
    {
        lock (_lock1)
        {
            lock (_lock2)
            {
                Thread.Sleep(3000);
                Console.WriteLine("A");
            }
        }
    });

    Thread code2 = new Thread(() =>
    {
        lock (_lock2)
        {
            Thread.Sleep(3000);
            lock (_lock1)
            {
                Console.WriteLine("B");
            }
        }
    });

    code1.Start();
    code2.Start();

    code1.Join();
    code2.Join();

    Console.WriteLine("Done");
}

最佳答案

这两个代码段都可能导致死锁,应该避免。只是一个巧合,第一个片段没有陷入僵局。在锁之间添加一些操作会增加获得死锁的可能性。
例如,如果在lock1和lock2之间添加Console.Writeline,则也会增加死锁的可能性。
您可以循环运行第一个代码段并收到死锁。例如,这段代码在一段时间后陷入僵局:

        static void Main(string[] args)
        {
            for (int i = 0; i < 1000; i++)
            {
                object _lock1 = new object();
                object _lock2 = new object();

                Thread code1 = new Thread(() =>
                {
                    lock (_lock1)
                    {
                        lock (_lock2)
                        {
                            Console.WriteLine("A");
                            Thread.Sleep(100);
                        }
                    }
                });

                Thread code2 = new Thread(() =>
                {
                    lock (_lock2)
                    {
                        lock (_lock1)
                        {
                            Console.WriteLine("B");
                            Thread.Sleep(100);
                        }
                    }
                });

                code1.Start();
                code2.Start();

                code1.Join();
                code2.Join();
            }
            Console.WriteLine("Done");
        }

关于c# - 为什么移动这条线会导致死锁?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53165458/

10-11 22:12
查看更多