Dead ends using wait and notifications

I am trying to understand how deadlocks are created. I realized that using two threads for two synchronized methods can create a dead end. Passed a lot of examples from the network.

Is it possible to create a deadlock with waiting and notification? Each time a thread is waiting, it will be notified. So how does this end at a dead end?

An example illustration will be helpful.

+4
source share
4 answers
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) {
        // ...
      }

}

The only way to prevent deadlocks is to make sure that all threads get locks in the same order - either they all do A, then B, or they all do B, then A.

, . , , .

+4

, , , - . , , :

public static void main(String[] args) {
   synchronized(String.class) {
       String.class.wait();
   }
}

. , , , , , , .

+1

, 1 A, . Thread 2 A. Thread 1 , 2 . . , 1. , . .

0

Something close to waiting / alerting a dead end:

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();
    }
}
0
source