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