Основная причина некорректного поведения кода — конфликт объектов блокировки приводит к тупиковой ситуации (deadlock).
В чём основная причина некорректного поведения кода
Основная причина некорректного поведения кода — конфликт объектов блокировки приводит к тупиковой ситуации (deadlock).
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В чём основная причина некорректного поведения кода
Нарушена иммутабельность объектов
Не обрабатывается состояние прерывания
Ухудшение производительности из-за блокировки
Конфликт объектов блокировки приводит к тупиковой ситуации
Избыточная синхронизация ресурсов
Неинициализированные состояния объектовimport java.util.concurrent.*;
class Competition { private final Object lock = new Object(); public void syncMethodA(Competition competitor) { synchronized (lock) { try { Thread.sleep(100); } catch (InterruptedException e) {} competitor.syncMethodB(this); } }
public void syncMethodB(Competition competitor) {
synchronized (lock) {
try { Thread.sleep(100); } catch (InterruptedException e) {}
competitor.syncMethodA(this);
}
}
}
public class FitnessApp { public static void main(String[] args) { Competition comp1 = new Competition(); Competition comp2 = new Competition();
Thread t1 = new Thread(() -> comp1.syncMethodA(comp2));
Thread t2 = new Thread(() -> comp2.syncMethodB(comp1));
t1.start();
t2.start();
}
}
Ответ
Основная причина некорректного поведения кода — конфликт объектов блокировки приводит к тупиковой ситуации (deadlock).
В данном примере два объекта Competition пытаются захватить блокировки друг друга:
comp1.syncMethodA(comp2)захватываетcomp1.lockи пытается вызватьcomp2.syncMethodB(this), которая пытается захватитьcomp2.lock.- Одновременно
comp2.syncMethodB(comp1)захватываетcomp2.lockи пытается вызватьcomp1.syncMethodA(this), которая пытается захватитьcomp1.lock.
В итоге оба потока ждут освобождения блокировки, которую держит другой поток — классический deadlock.
Чтобы избежать этой ситуации, нужно:
- Использовать один и тот же объект блокировки для всех синхронизированных методов.
- Избегать вложенных вызовов, которые требуют захвата нескольких блокировок.
- Применять таймауты или другие механизмы предотвращения взаимных блокировок.
Пример исправления — использовать один общий lock для всех объектов или перестроить логику без перекрестных вызовов с блокировками.