编写一个肯定会陷入死锁的程序 [已关闭]

2022-08-31 11:42:53

我最近在一次采访中问了这个问题。

我回答说,如果交错出错,就会发生死锁,但是面试官坚持认为,可以编写一个无论交错如何都会始终陷入死锁的程序 。

我们可以写这样的程序吗?你能给我指出一些这样的示例程序吗?


答案 1

更新:这个问题是我在2013年1月博客的主题。谢谢你的好问题!


我们如何编写一个无论线程如何调度都始终陷入死锁的程序?

下面是 C# 中的一个示例。请注意,该程序似乎不包含任何锁和共享数据。它只有一个局部变量和三个语句,但它以100%的确定性死锁。人们很难想出一个更简单的程序来确保僵局。

向读者练习#1:解释这种死锁是如何发生的。(评论中有答案。

给读者练习#2:在Java中演示相同的死锁。(答案在这里:https://stackoverflow.com/a/9286697/88656)

class MyClass
{
  static MyClass() 
  {
    // Let's run the initialization on another thread!
    var thread = new System.Threading.Thread(Initialize);
    thread.Start();
    thread.Join();
  }

  static void Initialize() 
  { /* TODO: Add initialization code */ }

  static void Main() 
  { }
}

答案 2

此处的闩锁确保在每个线程尝试锁定另一个线程时保持两个锁:

import java.util.concurrent.CountDownLatch;

public class Locker extends Thread {

   private final CountDownLatch latch;
   private final Object         obj1;
   private final Object         obj2;

   Locker(Object obj1, Object obj2, CountDownLatch latch) {
      this.obj1 = obj1;
      this.obj2 = obj2;
      this.latch = latch;
   }

   @Override
   public void run() {
      synchronized (obj1) {

         latch.countDown();
         try {
            latch.await();
         } catch (InterruptedException e) {
            throw new RuntimeException();
         }
         synchronized (obj2) {
            System.out.println("Thread finished");
         }
      }

   }

   public static void main(String[] args) {
      final Object obj1 = new Object();
      final Object obj2 = new Object();
      final CountDownLatch latch = new CountDownLatch(2);

      new Locker(obj1, obj2, latch).start();
      new Locker(obj2, obj1, latch).start();

   }

}

运行jconsole很有趣,它将正确显示“线程”选项卡中的死锁。


推荐