I'm trying to understand the synchronized() blocks in the program I wrote at the end of this post.
There are two threads (o and k) that use a shared lock object as a monitor for wait/notify.
o waits for k to start, inside the following synchronized block:
synchronized (lock) {
lock.wait(); // wait for K to be ready
}
k then notifies o and waits for it to print inside this block:
synchronized (lock) {
lock.notify(); // tell O to print
lock.wait(); // wait for O to print
}
My question is how can k enter the synchronized block with lock? Shouldn't o own lock (since it called wait())? The Java Tutorial says:
As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.
Here's the full program:
public class OK implements Runnable {
private static final Object lock = new Object(); // monitor for wait/notify
private boolean isO;
public OK(boolean b) {
isO = b;
}
public static void main(String[] args) throws InterruptedException {
Thread o = new Thread(new OK(true));
Thread k = new Thread(new OK(false));
o.start();
k.start();
k.join(); // when k is done, we're done
System.out.println("Done.");
}
public void run() {
// run method is called for both o and k, so we separate the logic
try {
if (isO) {
doO();
} else {
doK();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// O thread logic
private void doO() throws InterruptedException {
// K needs to be ready before I start
synchronized (lock) {
lock.wait(); // wait for K to be ready
}
System.out.print("O");
synchronized (lock) {
lock.notify(); // tell K I printed
}
}
// K thread logic
private void doK() throws InterruptedException {
// O is waiting for me to start
synchronized (lock) {
lock.notify(); // tell O to print
lock.wait(); // wait for O to print
}
System.out.println("K");
}
}
lock.wait releases the monitor. See the Object.wait() javadoc:
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
Intuition may tell you that "synchronized (lock)" means that it hold that lock during the entire block it wraps; but that is not how it works.
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