线程中的死锁情况?

时间:2010-01-04 06:44:41

标签: java multithreading

想知道线程中的死锁条件是什么,因为在我研究过如何避免死锁情况的许多书中,我只是想知道什么是死锁情况和示例代码?

8 个答案:

答案 0 :(得分:21)

死锁是并发程序无法继续的情况。

  

线程正在等待另一个   线程,而另一个线程是   等待第一个帖子   完成。

常用的现实世界的例子是交通流量。

alt text

在另一个队列移动之前,没有流量可以移动。

您可以找到关于死锁here的良好讨论。

更新:这是我在网上找到的一个java example(Oreilly书)。它对此有意见,因此您可以轻松理解它。

Dining Philosophers problem是另一个了解死锁的好例子。

删除了死的Imageshack链接

死锁检测和死锁预防是在了解死锁时可能有用的两个相关领域。

答案 1 :(得分:6)

死锁是指A等待B而B等待A。

所以你可以在主题A:

while(B.incomplete()){
    B.wait();
} A.complete = true;

并且在主题B中有:

while(A.incomplete()){
    A.wait();
} B.complete = true;

答案 2 :(得分:2)

以下是不使用wait的死锁示例。只要你有同步,就有可能陷入僵局。

public class Deadlock {
  static class Deadlocker {
    private Deadlocker other;

    public void setOther(Deadlocker other) {
      this.other = other;
    }

    synchronized void doSomethingWithOther() {
      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
      }
      other.doSomething();
    }

    synchronized void doSomething() {
    }
  }

  public static void main(String[] args) {
    final Deadlocker d1 = new Deadlocker();
    final Deadlocker d2 = new Deadlocker();
    d1.setOther(d2);
    d2.setOther(d1);

    Thread t1 = new Thread() {
      public void run() {
        d1.doSomethingWithOther();
      }
    };

    Thread t2 = new Thread() {
      public void run() {
        d2.doSomethingWithOther();
      }
    };

    t1.start();
    t2.start();
  }
}

t1位于d1.doSomethingWithOther()时(因此锁定d1)并且t2位于d2.doSomethingWithOther()时出现死锁(因此具有锁定d2)。当每个线程试图在对象上调用doSomething() 其他线程锁定时,它们最终会卡住,等待彼此。

请注意,死锁不一定只涉及两个线程。它可以有任何大小的循环。更糟糕的是,一旦发生死锁,任何其他尝试获取死锁线程已经持有的锁的线程最终都会自动陷入僵​​局,即使没有处于循环中。

答案 3 :(得分:1)

死锁是由资源争用引起的,如果没有某种资源控制(例如依赖于两个资源锁的图形周期),则无法直接解决该问题。

最常见的(通常用于说明)死锁场景之一是锁定反转:

  • 考虑一个具有两个关键资源(resA,resB)和两个锁(lockA,lockB)的应用程序。每个资源都受相应的锁保护(resA => lockA,resB => lockB)。
  • 两个资源争用资源,线程A保留lockA(因此资源A),然后暂停上下文切换),然后才能保留lockB。线程B接收控制,保留lockB然后尝试保留lockA。这会导致线程被挂起并且控制权返回给线程A,线程A在lockB上等待,该线程被保存为线程B.

在这种情况下,由于两个竞争资源(lockA和lockB)上的两个线程之间存在循环依赖关系,因此无法在没有单独干预的情况下解析,因此会出现死锁。

这可以通过以下任何一种方式解决:

  1. 确保按顺序解决两个锁定(不是最佳选择)
  2. 一次只为每个关键部分持一个锁(即在尝试获取lockB之前释放lockA)

答案 4 :(得分:1)

想象一下以下的逻辑线程。

  1. 在catch-22中,小说, 由于精神错乱,战斗机飞行员将被停飞。他可以证明他不会疯狂,以便他可以再次飞行,以证明精神错乱的情况。但是,通过询问,想要闯入战斗以危及他的生命将证明他是疯了。

  2. 朝鲜希望七国集团在停止铀精炼之前提供经济援助。美国和日本说“没办法,因为他们在获得援助后会背叛。”

  3. 系统重启冲突。

    1. 系统不会关闭,直到 所有用户进程都已经完成 终止。
    2. 编辑器,用户进程不会 除非编辑已经终止 保存。
    3. 除非是,否则无法保存编辑内容 usb驱动器存在是因为 编辑可执行文件是从 usb驱动器。
    4. usb驱动器被拆卸是因为 驱动程序升级。 USB驱动器 直到没有安装 系统关闭并重新启动。
  4. Android机器人有主要指令

    机器人不会伤害人类,也不会通过不作为让人类受到伤害。

    机器人必须服从人类给予的任何命令,除非此类命令与第一指令冲突。

    机器人必须保护自己的存在,只要这种保护不与第一或第二指令冲突。

  5. 基地的人类居住者派机器人检索无线电有源电源。如果没有动力源,基地就会关闭,人类的殖民地就会死亡。但是机器人发现电源是如此强大且没有屏蔽,处理它会导致机器人发生故障并对人类群体构成危险。

答案 5 :(得分:0)

死锁是指两个(或更多)线程都在等待另一个线程完成。线程A无法完成,直到线程B执行某些操作,并且线程B无法完成,直到线程A执行其他操作。

答案 6 :(得分:0)

  

等待每个线程时线程死锁   其他的是释放一些资源,但是   通过执行阻塞等待,   他们没有释放资源   其他线程需要   解除封锁。线程不能做任何   直到资源进展   释放,但因为他们不是   进步,资源将   永远不会被释放,线程是   锁定,因此“死锁。”

Stephen Toub的nice article可能对你有所帮助。

答案 7 :(得分:0)

DeadLock is a situation when first thread is waiting for second Thread, 

while  Second Thread is waiting for first thread's completion.

查看此流量死锁以更好地了解UnderStand DeadLock情况

enter image description here

enter image description here

**Java Code Demo**

public class DeadLockDemo 
{
   public static Object object1 = new Object();
   public static Object object2 = new Object();
   private int index;
   public static void main(String[] a) {
      Thread t1 = new Thread1();
      Thread t2 = new Thread2();
      t1.start();
      t2.start();
   }
   private static class Thread1 extends Thread {
      public void run() {
         synchronized (object1) {
            System.out.println("Thread 1: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");
            synchronized (object2) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   }
   private static class Thread2 extends Thread {
      public void run() {
         synchronized (object2) {
            System.out.println("Thread 2: Holding lock 2...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 1...");
            synchronized (object1) {
               System.out.println("Thread 2: Holding lock 2 & 1...");
            }
         }
      }
   }
}

enter image description here