繁体   English   中英

线程中的死锁情况?

[英]Deadlock situation in threads?

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

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

一个线程正在等待另一个线程,而另一个线程正在等待第一个线程的完成。

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

替代文字

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

你可以在这里找到关于死锁的好讨论。

更新:这是我在网上找到的一个java 示例 (Oreilly书)。 它有评论,所以你可以很容易地理解它。

用餐哲学家问题是另一个了解死锁的好例子。

删除死了Imageshack链接

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

死锁是A等待B而B等待A.

所以你可以在线程A:

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

并在线程B中:

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

这是一个不使用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();
  }
}

t1d1.doSomethingWithOther()时发生死锁(因此在d1上有锁定)并且t2d2.doSomethingWithOther() (因此在d2上有锁定)。 当每个线程试图在对象上调用doSomething()时, 另一个线程都锁定,它们最终会卡住,等待彼此。

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

死锁是由资源争用引起的,如果没有某种资源控制(例如依赖于两个资源锁的图形循环),这种资源争用是不可直接解决的。

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

  • 考虑一个具有两个关键资源(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)

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

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

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

  3. 系统重启冲突。

    1. 在所有用户进程终止之前,系统不会关闭。
    2. 编辑器,除非已保存编辑,否则用户进程不会终止。
    3. 除非存在usb驱动器,否则无法保存编辑,因为编辑器可执行文件是从usb驱动器调用的。
    4. 由于驱动程序升级,usb驱动器已卸下。 在系统关闭并重新启动之前,无法安装USB驱动器。
  4. Android机器人有主要指令

    机器人不会伤害人类,或者通过不作为,允许人类受到伤害。

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

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

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

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

线程在等待彼​​此释放某些资源时发生死锁,但是通过执行阻塞等待,它们不会释放其他线程为解除阻塞而需要的资源。 在释放资源之前,线程无法取得任何进展,但由于它们没有取得进展,资源永远不会被释放,线程被锁定,从而“死锁”。

Stephen Toub的一篇好文章可能对你有所帮助。

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

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

请参阅此流量死锁以获得更好的UnderStand DeadLock情况

在此输入图像描述

在此输入图像描述

**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...");
            }
         }
      }
   }
}

在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM