Java 使用wait和notify的死锁

Java 使用wait和notify的死锁,java,deadlock,Java,Deadlock,我试图理解死锁是如何产生的。我知道,通过在两个同步方法上使用两个线程,可以创建死锁。 浏览了网上的许多例子 是否可以使用wait和notify创建死锁? 每次线程处于等待状态时,都会收到通知。那么,这是如何陷入僵局的呢 举例说明会很有帮助 除非某些代码明确通知处于等待状态的线程,否则不会通知该线程。因此,您正在寻找的示例非常简单: public static void main(String[] args) { synchronized(String.class) { Str

我试图理解死锁是如何产生的。我知道,通过在两个同步方法上使用两个线程,可以创建死锁。 浏览了网上的许多例子

是否可以使用wait和notify创建死锁? 每次线程处于等待状态时,都会收到通知。那么,这是如何陷入僵局的呢


举例说明会很有帮助

除非某些代码明确通知处于等待状态的线程,否则不会通知该线程。因此,您正在寻找的示例非常简单:

public static void main(String[] args) {
   synchronized(String.class) {
       String.class.wait();
   }
}
这个永远挂着。但从技术上讲,这不是死锁,死锁需要两个或多个线程参与一个封闭的循环,每个线程等待下一个线程解除对它的阻塞

Deadlock is caused when two threads try to obtain the same, multiple locks in different order:

    // T1
    synchronized (A) {
      synchronized (B) {
        // ...
      }
    }

    // T2
    synchronized (B) {
      synchronized (A) {
        // ...
      }

}
防止死锁的唯一方法是确保所有线程都以相同的顺序获得锁——要么都执行A然后执行B,要么都执行B然后执行A


如果没有多个锁,则不会出现死锁。但是,您可能会遇到线程饥饿或其他类似死锁的情况。

假设线程1在方法a上进入同步块,然后等待。然后,线程2尝试进入方法A上的同步块。线程1正在等待通知,线程2正在等待同步块。一切都在等待。其他线程必须通知线程1正在等待的对象。这只是一种可能造成死锁的场景。有各种各样的方法可以做到这一点

接近等待/通知死锁的事件:

public class Example
{
    volatile boolean isNotified = false;

    public synchronized void method1() {
        try
        {
            isNotified = false;
            while (!isNotified)
                wait();
            notifyAll();
            System.out.println("Method 1");
        } catch (InterruptedException e) {/*NOP*/}
    }

    public synchronized void method2() {
        try {
            isNotified = true;
            while (isNotified)
                wait();
            notifyAll();

            System.out.println("Method 2");
        } catch (InterruptedException e) {/*NOP*/}

    }

    public static void main(String[] args)
    {
        Example example = new Example();

        Thread thread1 = new Thread()
        {

            public void run()
            {
                example.method1();
            }
        };

        Thread thread2 = new Thread()
        {

            public void run()
            {
                example.method2();
            }
        };

        thread1.start();
        thread2.start();
    }
}

许多例子和解释中的一个:如果JVM在无法取得进展的情况下,会在其中一个被阻止的线程中引发一些异常,那就太好了。@Ingo为什么JVM的工作应该是修复糟糕的编程?@b1nary.atr0phy您会称NullPointerException为修复糟糕的编程吗?不,这只是一个问题的诊断,这是JVM的工作。@Ingo苹果和橙子。JVM是否应该检测您是否想要--x而不是x++呢?@b1nary.atr0phy另一方面,JVM为什么要检测空指针或内存不足?回答:因为1)它可以,2)它使我们的生活更轻松。引用
Object#wait
javadoc:“线程释放此监视器的所有权并等待[…]”这会如何造成死锁?