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");
}
}