Why does notifyAll () not resume other threads in this simple case?

I am new to Java concurrency. I have a simple object with 3 ways, each of which corresponds to the code started by 3 different threads. Why doesn't the notifyAll () operator release the wait in the other two threads in this case?

public class Main {
static class Obj {
      synchronized void t1 () {
          System.out.println("T1 ran");
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          notifyAll();
      }
     synchronized void t2 () {
         try {
             wait();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         System.out.println("T2 ran");
     }
    synchronized void t3() {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("T3 ran");
    }
}

public static void main(String[] args) {
    final Obj o = new Obj();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t1();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t2();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t3();
        }
    }).start();
}}

      

I expected: T1 ran ~~ pause for 1 second ~~ T2 ran T3 ran

I got: T1 ran

+3


source to share


3 answers


Thread.sleep

does not release or block locks in a way wait

, so synchronization is still full and no other threads will be allowed to inject their methods while they sleep.

If you replace

Thread.sleep(1000);

      



from

wait(1000);

      

other threads will be allowed to grab the same lock, introduce methods, start waiting and the sample will work as you expected.

+6


source


Your three methods: synchronized

on the same instance. And Thread#sleep(..)

does not release the lock acquired with synchronized

. Thus, the executing thread t1

acquires the lock, sleeps for a second, wakes up, calls notifyAll()

and exits.

Then your other two threads get rotated on execution and call wait()

. But there is nothing left to notify them, so your apps are blocked.



You have a race condition. Change the order in which the threads are fired, or run it as if you have enough time to see different behavior.

+3


source


If I am correct, threads for methods t2 and t3 cannot inject the method, since thread t1 is blocking the object all the time, as it is a synchronized method. And by the time t2 and t3 actually ran notifyAll (), this had already happened, so they wait forever :(

Try running t2 and t3 first, then t1.

As already pointed out. Thread.sleep () does not release locks or monitors, so the method cannot be injected by other threads as it is marked synchronized: Thread.sleep ()

+3


source







All Articles