Пример из книги Герберта Шилдта
package testpack;
class Deadlock implements Runnable {
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying to call B.last()");
b.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
A a = new A();
B b = new B();
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
}
Не понимаю почему здесь получается взаимная блокировка.
Один поток заходит в foo, второй в bar. И, насколько я понимаю, здесь могу уже ошибаться тк не слишком силен в данной теме, foo блокирует B b обьект, а bar блокирует A a.
И вот когда код доходит до выполнения last() метода я не понимаю, почему
synchronized void bar(A a) {
//..//
a.last();
}
не может выполнить его, метод bar ведь сам и удерживает мьютекс обьекта а, который и требуется для выполнения a.last() метода. Ну и соответственно для B b обьекта.