Why is the thread not waiting for notification ()?

Why doesn't the thread wait for notify() ? The thread starts and then goes to the wait pool, but after that it goes to execution.

 public class JavaApplication2 { public static void main(String [] args) { ThreadB b = new ThreadB(); synchronized(b) { b.start(); try { System.out.println("1"); b.wait(); } catch (InterruptedException e) {} System.out.println("Total is: " + b.total); } } } class ThreadB extends Thread { int total; @Override public void run() { synchronized(this) { total += 1; //notify(); } } } 
+4
source share
6 answers

You are synchronizing the stream object itself, which is misuse. It happens that a dying thread of execution always calls notify in the Thread : Thread.join relies on this . Therefore, it is clear why you are getting the same behavior with and without your notify .

Solution: use a separate object to coordinate flows; this is standard practice.

+7
source

The notifyAll() method is called for the Thread object of the terminating thread. This fact is strangely documented in Thread.join description with the following sentence:

As the thread completes, this thisnotifyAll method is called. It is recommended that applications do not use wait, notify, or notifyAll for Thread instances.

Thus, unless you explicitly read the description of `join`, which you do not necessarily need, you will not know the reason for the strange behavior.

+2
source

You cannot depend on whether you return from expectation to notification: "interruptions and false awakenings are possible." In general, you should wrap the wait call in a loop while the thread has to wait.

+1
source

If you try to synchronize your code with any other object that ThreadB , you will find that it never ends. This is due to the fact that there is a hidden call to notify .

Although I don’t know anywhere that this is indicated, Thread notifies itself when it ends. This is implied in the way the join method is implemented. This is the code for join :

 public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } 

(From JDK7 source code)

As you can see, wait calls make sense only if somewhere there is a notify call that is called after the stream ends. The same call to notify is what allows your program to terminate.

+1
source

You have nested synchronized {} constructs in two places. These constructs seem strange: a thread does not respond to notifications at all and only resumes when ThreadB (b) is completed. Remove this:

 public class JavaApplication2 { public static void main(String[] args) { ThreadB b = new ThreadB(); b.start(); try { System.out.println(" ### Waiting for notify"); synchronized (b) { b.wait(); } System.out.println(" ### Notified"); } catch (InterruptedException e) { } System.out.println("### Total is: " + b.total); } } class ThreadB extends Thread { int total; @Override public void run() { total += 1; System.out.println(" *** Ready to notify in 5 secs"); try { Thread.sleep(5000); } catch (InterruptedException e) { } System.out.println(" *** Notification sent"); synchronized (this) { notify(); } System.out.println(" *** 5 sec post notification"); try { Thread.sleep(5000); } catch (InterruptedException e) { } System.out.println(" *** ThreadB exits"); } } 

It is likely that the code is working correctly: upon notification (), the current main thread resumes after 5 seconds and before we see the message that ThreadB terminates. Upon notification (), the commented main thread resumes after 10 seconds and after the ThreadB termination message, because notify () is called anywhay from another code. Marco Topolnik explains why and where this call comes from "offstage" () ().

0
source

I did the same wait / notification test when reading OCP SE 7, good catch. I think we should let the author explain.

0
source

All Articles