Witam
W poniższym kodzie wywołuje metodę synchronized, która zakłada blokadę na obiekt R2. Wewnątrz tej metody zakładam kolejną blokadę wewnątrz bloku synchronized na inny obiekt. Program działa tak jak powinien i jestem zaskoczony. Co de facto się dzieje wewnątrz metody run obiektu R2? Jeżeli zamiast synchronized(r1) napiszę synchronized(this) program wyrzuci wyjątek IllegalMonitorStateException. Rozumiem to tak, że poprzez wywołanie metody run() obiekt R2 zyskuje dla siebie blokadę. Następnie w ciele metody wywołuje wywołuje blok synchronizowany względem obiektu r1 czyli obiekt R2 ma 2 blokady?
class R1 implements Runnable {
{ Thread.currentThread().setName("R1"); }
@Override synchronized public void run() {
try {
while(true){
Thread.sleep(5000);
System.out.println("zadanie R1 start()");
wait();
}
}
catch(InterruptedException e) {
System.out.println("przerwanie: " + e);
}
System.out.println("R1 wyjscie z wait()");
}
}
class R2 implements Runnable {
{ Thread.currentThread().setName("R2"); }
private R1 r1;
public R2(R1 r1) {
this.r1 = r1;
}
@Override synchronized public void run() {
try {
while(true) {
System.out.println("zadanie R2 start");
Thread.sleep(5000);
synchronized(r1) { // synchronized(this) nie działa - zglasza wyjatek IllegalMonitorStateException.
r1.notify();
}
}
}
catch(InterruptedException e) {
System.out.println("przerwanie R2: " + e);
}
System.out.println("R2 wyjscie z wait()");
}
}
public class WaitNotifyTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
FLAG flag = new FLAG(true);
R1 r1 = new R1();
R2 r2 = new R2(r1);
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(r1);
Thread.sleep(1000);
exec.execute(r2);
exec.shutdown();
}
}