Java 线程中的死锁情况?

Java 线程中的死锁情况?,java,multithreading,Java,Multithreading,想知道线程中的死锁情况是什么,因为在我研究过如何避免死锁情况的许多书中,我只想知道什么是死锁情况以及死锁的示例代码?死锁是并发程序无法继续的情况 一个线程正在等待另一个线程 线程,而另一个线程是 正在等待第一个线程的 完成 现实世界中常用的例子是交通流 在另一个队列移动之前,任何通信都不能移动 您可能会发现一个关于死锁的好讨论 更新:这是我在网上找到的一个java(Oreilly书)。它对此有评论,因此您可以轻松理解 是理解死锁的另一个好例子 拆下固定的影像棚链接 死锁检测和死锁预防是学习死锁

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

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

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

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

在另一个队列移动之前,任何通信都不能移动

您可能会发现一个关于死锁的好讨论

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

是理解死锁的另一个好例子

拆下固定的影像棚链接


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

死锁是指两个(或更多)线程各自等待另一个线程完成。线程A在线程B执行某些操作之前无法完成,而线程B在线程A执行其他操作之前无法完成。

死锁是指A等待B,B等待A

因此,您可以在线程A中:

while(B.incomplete()){
    B.wait();
} A.complete = true;
在线程B中:

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

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

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

  • 考虑一个具有两个关键资源(resA、resB)和两个锁(lockA、lockB)的应用程序。每个资源都受到相应锁的保护(resA=>lockA,resB=>lockB)
  • 两个资源正在争夺资源,线程A保留了锁A(因此资源A)并在能够保留锁B之前被挂起以进行上下文切换)。线程B接收控制权,保留锁B,然后尝试保留锁A。这导致线程被挂起,控制权返回到线程A,线程A正在等待锁B,锁B由线程B持有
在这种情况下,由于两个争用资源(lockA和lockB)上的两个线程之间存在循环依赖关系,因此会出现死锁,如果没有单独的干预,这是无法解决的

这可以通过以下两种方法解决:

  • 确保两个锁按顺序解决(不是最佳选择)
  • 每次仅为每个关键部分持有一把锁(即,在尝试获取锁B之前释放锁a)

  • 下面是一个不使用
    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()
    时,它们最终会被卡住,等待对方


    请注意,死锁不一定只涉及两个线程。可以有任何大小的循环。更糟糕的是,一旦发生死锁,任何试图获取死锁线程已经持有的锁的其他线程都将最终成为有效的死锁,即使不在循环中。

    想象一下下面的逻辑线程

  • 在《第二十二条军规》中, 战斗机飞行员因精神错乱而被停飞。他可以证明自己没有精神错乱,这样他就可以再次飞行。但是,如果他问,想飞到战场上危及自己的生命,就表明他疯了

  • 朝鲜希望七国集团在停止提炼铀之前提供经济援助。美国和日本表示“不可能,因为他们在得到援助后会背弃。”

  • 系统重新启动冲突

  • 该系统将不会关闭,直到 所有用户进程都已完成 终止
  • 在编辑器中,用户进程不会 除非编辑已完成,否则终止 拯救
  • 除非 usb驱动器存在,因为 已从调用编辑器可执行文件 usb驱动器
  • usb驱动器已卸载,因为 一个驱动程序升级的例子。usb驱动器 在安装之前无法安装 系统关闭并重新启动
  • Android机器人具有基本指令

    机器人不得伤害人类,也不得因不作为而允许人类受到伤害

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

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

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

    线程在等待每个线程时死锁 其他方法释放一些资源,但是 通过执行阻塞等待, 他们没有释放资源 其他线程需要 解除封锁。这些线不能做任何改变 在资源到位之前取得进展 释放了,但因为他们没有 如果取得进展,资源将 永远不要释放,线程是 锁定,从而“死锁”

    Stephen Toub的A可能会对你有所帮助

    DeadLock is a situation when first thread is waiting for second Thread, 
    
    while  Second Thread is waiting for first thread's completion.
    
    查看此流量死锁以更好地了解死锁情况


    我意识到这是一个非常简单的例子,但你明白了吧?我喜欢这个图表。这就是我小时候教授给我看的
    **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...");
                }
             }
          }
       }
    }