Senior
Kāda ir galvenā kļūda koda uzvedībā? Objektu nemainīgums ir pārkāpts Pārtraukšanas stāvoklis netiek pārvaldīts Bloķēšanas objektu konflikts noved pie deadlock Pārāk liela resursu sinhronizācija Objektu neizveidoti stāvokļiimport 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(); } }
sobes.tech AI
Atbilde no AI
Основная причина некорректного поведения кода — конфликт объектов блокировки приводит к тупиковой ситуации (deadlock).
В данном примере два объекта Competition пытаются захватить блокировки друг друга:
comp1.syncMethodA(comp2)захватываетcomp1.lockи пытается вызватьcomp2.syncMethodB(this), которая пытается захватитьcomp2.lock.- Одновременно
comp2.syncMethodB(comp1)захватываетcomp2.lockи пытается вызватьcomp1.syncMethodA(this), которая пытается захватитьcomp1.lock.
В итоге оба потока ждут освобождения блокировки, которую держит другой поток — классический deadlock.
Чтобы избежать этой ситуации, нужно:
- Использовать один и тот же объект блокировки для всех синхронизированных методов.
- Избегать вложенных вызовов, которые требуют захвата нескольких блокировок.
- Применять таймауты или другие механизмы предотвращения взаимных блокировок.
Пример исправления — использовать один общий lock для всех объектов или перестроить логику без перекрестных вызовов с блокировками.