Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a notify signalled on thread finish? Why does this code sample work?

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?

like image 526
Cratylus Avatar asked Jul 23 '12 09:07

Cratylus


People also ask

How do you notify threads?

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.

How do you notify certain threads in Java?

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.

What is the use of notify?

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.

What is the difference between notify and notify all method?

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.


2 Answers

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?

like image 99
Peter Lawrey Avatar answered Oct 18 '22 19:10

Peter Lawrey


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.

like image 39
Marko Topolnik Avatar answered Oct 18 '22 18:10

Marko Topolnik