1) Does a thread relinquish it's lock as soon as notify is invoked within that threads synchronized code block, or once the synchronized code block is exited?
For instance, it seems like without specifying thread priority, my Process class will execute from top to bottom. Produce will be called first, it will do stuff, then wait(); consume will run, and then it hits notify(), which will print "Done" or will there be a 5 second delay first, then "Done" will be printed?
2) Also, if I had a third synchronized method/thread, that does not wait or notify and just runs, can I predict the order in which my operations are executed a priori?
3) Finally, how does notify() know what thread to 'wake up'? Like, let's say I have multiple Processes each executing 2 threads simultaneously, and each Process A, B, and C evoke notify( ). Is each notify( ) local to each Process? In other words, if Process A calls notify( ), can that wake up a waiting thread in Process B? So far I've seen synchronized called on (this), which makes me think its referring to a particular object class, which in turn makes me think that all notify( )'s called in synchronized blocks are bound by whatever this in synchronized(this) is referring to, so there would be no cross-over.
public class Process {
public void produce( ) {
synchronized(this) {
// do stuff
wait( );
System.out.println("Done");
}
}
public void consume( ) {
synchronized(this) {
// stuff
notify();
Thread.sleep(5000);
}
}
}
You can write a simple program to test this
public static void main(String[] args) throws Exception {
final Process e = new Process();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
e.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
e.produce();
}
This program waits 5000 milliseconds and prints
Done
As for your questions
1) Does a thread relinquish it's lock as soon as notify is invoked within that threads synchronized code block, or once the synchronized code block is exited?
The javadoc of notify()
states
If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation.**strong text A thread waits on an object's monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object
So, no, the thread does not relinquish control of the lock when calling notify()
. That will happen when code exits the synchronized
block.
2) Also, if I had a third synchronized method/thread, that does not wait or notify and just runs, can I predict the order in which my operations are executed a priori?
You can estimate, but you can't be certain. Execution happens at the discretion of the Thread scheduler.
3) Finally, how does notify() know what thread to 'wake up'?
The call doesn't know. The Thread scheduler knows and chooses. You cannot control this.
The javadoc for wait()
and notify()
state
This method should only be called by a thread that is the owner of this object's monitor.
and
IllegalMonitorStateException - if the current thread is not the owner of this object's monitor.
So you can only call them on objects when you are inside a synchronized
block that is synchronized on that object.
In your code example, the call
wait();
is implicitly doing
this.wait();
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