Use of notify() and notifyAll() doesn't work in the code

java, multithreading, notify, synchronize, wait

Solution

General comment: the javadoc of `Object#wait` states that

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop.

So a waiting thread can wake up without being notified and your design should take that into account by waiting in a loop and checking for an exit condition (cf example in the javadoc).

In your case, however, the issue is slightly different. According to the `Thread#join` javadoc:

As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

So when your Calculator finishes, it calls `this.notifyAll()` and wakes up all the waiting threads.

How to fix it?

You should use a separate lock object, similar to: `private final Object lock = new Object();` in your Calculator and provide a getter for the Readers.

Problem

I pasted the code below. That is commented enough. Clear about wait(). When comes here it jumps to another block. That part i am oaky. My doubt is Why we are using notify and notifyAll(). If you remove these two from below code, it works fine. ``` class Reader extends Thread{ Calculator c; //here we didn't write no-arg constructor. Note this. // one - arg constructor. public Reader(Calculator calc){ c = calc; } public void run(){ synchronized(c){ // 2. Acquiring the object lock and executes this code of block. try{ System.out.println("Waiting for calculation..."); c.wait(); // 3. Release the object lock and moves to the second synchronize block below // 6. Later the object get the lock here and moves on. }catch(InterruptedException e){ } System.out.println("Total is: "+c.total); } } public static void main(String[] args){ //Instantiating new with no-arg. One more doubt, How this work without no-arg constructor above. Please explain. Calculator calculator = new Calculator(); //Instantiating new with one-arg new Reader(calculator).start(); new Reader(calculator).start(); new Reader(calculator).start(); // 1. Once you start here it will goto first synchronized code block above calculator.start(); } } class Calculator extends Thread{ int total; public void run(){ synchronized(this){ // 4. This block acquires that object lock and executes the code block below. for(int i=0;i<100;i++){ total +=i; } // 5. As per documentation, If we give notify() it will release the object lock to only one thread object of its choice. // If we use notifyAll(); it will release the object lock to all the three thread object. notify(); // My doubt here is without using the notify or notifyAll it is working fine. // As per docs if we use notify() only one object should get the lock. That is also not working here. } } } ```

Original source

Related problems