I am looking in some puzzles for threads and I can't figure out why the following consistently prints 999999
:
class Job extends Thread {
private Integer number = 0;
public void run() {
for (int i = 1; i < 1000000; i++) {
number++;
}
}
public Integer getNumber() {
return number;
}
}
public class Test {
public static void main(String[] args)
throws InterruptedException {
Job thread = new Job();
thread.start();
synchronized (thread) {
thread.wait();
}
System.out.println(thread.getNumber());
}
}
There is no notify
on the same lock (and spurious wakeup seem to be ignored).
If a thread finishes does a notify get signalled or something?
How come main
prints the result and not get "stuck" waiting?
Java Thread notify() methodThe notify() method of thread class is used to wake up a single thread. This method gives the notification for only one thread which is waiting for a particular object.
You don't / can't notify a specific thread. You call notify() on a lock object. This wakes up one of the threads1 that is waiting on the lock.
1 : to give formal notice to notify a family of the death of a relation She notified the police about the accident. 2 : to give notice of or report the occurrence of He notified his intention to sue. She notified my arrival to the governor.
In case of multiThreading notify() method sends the notification to only one thread among the multiple waiting threads which are waiting for lock. While notifyAll() methods in the same context sends the notification to all waiting threads instead of single one thread.
In the Javadoc for Java 7 Thread.join(long)
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Using a Thread directly this way is considered bad practical. Note: wait() could end for any number of reasons, possibly spuriously.
Based on a puzzler related to @Voo's comment. The point is you shouldn't play with the internal behaviour of Thread as this is more likely to lead to confusion.
public static String getName() {
return "MyProgram";
}
public static void main(String... args) {
new Thread() {
public void run() {
System.out.println("My program is " + getName());
}
}.start();
}
What does this program print?
For clarification, I have modified your code to this:
Job thread = new Job();
thread.start();
final Object lock = new Object();
synchronized (lock) { lock.wait(); }
System.out.println(thread.getNumber());
Now it blocks. That's a first-hand confirmation of what @Nitram has explained in his answer. If you care to have a look at the Thread
implementation code, it will be quite obvious why this is the observed behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With