public class test implements Runnable {
A a = new A();
B b = new B();
test() {
Thread.currentThread().setName("Главный поток");
Thread t = new Thread(this, "Соперничающий поток");
t.start();
a.foo(b); // получить блокировку для объекта a в этом потоке исполнения
System.out.println("Назад в главный поток");
}
public void run() {
b.bar(a); // получить блокировку для объекта b в другом потоке исполнения
System.out.println("Назад в другой поток");
}
public static void main(String[] args) {
new test();
}
}
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " вошел в метод A.foo()");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("class A is break");
}
System.out.println(name + " пытается вызвать метод B.last()");
b.last();
}
synchronized void last() {
System.out.println("В методе A.last()");
}
}
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " вошел в метод B.bar()");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("class B is break");
}
System.out.println(name + " пытается вызвать метод A.last()");
a.last();
}
synchronized void last() {
System.out.println("В методе A.last()");
}
}
Главный поток входит в монитор объекта A. Соперничающий входит в монитор объекта B. Почему когда поток исполнения в объекте A пытается вызвать синхронизированный метод для объекта B он блокируется? Почему когда поток исполнения в объекте B пытается вызвать синхронизированный метод для объекта A, то он будет ждать вечно? Я так понял монитор распространяется на весь объект что-ли, а не на метод в объекте?
Да, монитор распространяется на весь объект. Запись
class A {
synchronized void aVoid() {
}
}
аналогична записи
class A {
void aVoid() {
synchronized(this) {
}
}
}
То есть, при выполнении синхронизированного метода или блока, синхронизированного с текущим объектом, весь объект блокируется, и у него нельзя вызвать никакие другие синхронизированные методы. Такая взаимная блокировка, как в вашем примере, называется Deadlock.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Пытаюсь написать запрос на hql, который вернет одну цифру методом getSingleResult(), все вполне сносно работало до тех пор, пока не появилась нужда...
Я знаю, что если не указывать аргументы (вообще без угловых скобок) для классов-дженериков, то аргументами будет считаться тип Objcect, и что так...
Подскажите как можно реализовать метод который должен возвращать самый малый элемент