J'essaie de comprendre le synchronized()
dans le programme que j'ai écrit à la fin de ce billet.
Il y a deux fils ( o
y k
) qui utilisent une lock
comme moniteur pour wait/notify.
o
attend k
pour commencer, à l'intérieur du bloc synchronisé suivant :
synchronized (lock) {
lock.wait(); // wait for K to be ready
}
k
notifie ensuite o
et attend qu'il s'imprime à l'intérieur de ce bloc :
synchronized (lock) {
lock.notify(); // tell O to print
lock.wait(); // wait for O to print
}
Ma question est de savoir comment k
entrer dans le bloc synchronisé avec lock
? Ne devrait-on pas o
propre lock
(puisqu'il a appelé wait()
) ? Le site Java Tutorial dit :
Tant qu'un thread possède un verrou intrinsèque, aucun autre thread ne peut acquérir le même verrou. L'autre thread se bloque lorsqu'il tente d'acquérir le verrou.
Voici le programme complet :
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");
}
}