JavaRush /Курсы /Java Multithreading /Стратегии избегания DeadLock

Стратегии избегания DeadLock

Java Multithreading
7 уровень , 5 лекция
Открыта
Стратегии избегания DeadLock - 1

— Привет, Амиго!

Хочу рассказать тебе про пару стратегий избегания дедлоков.

Самая лучшая стратегия – это продуманная архитектура и набор правил, когда можно использовать блокировки (захват мютексов) и в каком порядке. Классический способ борьбы с проблемой — разработка иерархии блокировок, установление правила, что некоторые блокировки никогда не могут захватываться в состоянии, в котором уже захвачены какие-то другие блокировки.

Иногда, например, блокировкам присваивают уровни, требуя при этом от нити захватывать блокировки в порядке от большего уровня к меньшему, но не в обратном. Так же нельзя захватывать несколько блокировок одного уровня.

Например, в предыдущем примере про рыцарей, каждому рыцарю можно добавить его уникальный номер (id) и потребовать, чтобы блокировки происходили от большего id к меньшему.

Пример
class KnightUtil
{
 public static void kill(Knight knight1, Knight knight2)
 {
  Knight knightMax = knight1.id > knight2.id ? knight1: knight2;
  Knight knightMin = knight1.id > knight2.id ? knight2: knight1;

  synchronized(knightMax)
  {
   synchronized(knightMin)
   {
    knight2.live = 0;
    knight1.experience +=100;
   } 
  }
 }
}

— Красивое решение.

— Это очень простое решение, но мне нравится. Надеюсь, оно тебе пригодится, когда ты будешь думать, как решать возможные проблемы с дедлоками.

— Спасибо, Элли.

Комментарии (50)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
26 апреля 2025
/* Комментарий не удален */
Denis Odesskiy Уровень 47
3 мая 2024
Тут никто не выигрывает, оба рыцаря убивают друг друга. Но можно добавить победу по какому-то критерию, например если у одного больше опыта или жизни то он выиграет. Опыт или жизнь можно генерировать рандомно, можно добавить в конструктор рыцарю имя, создать несколько рыцарей с разными именами, несколько потоков, статическую переменную счетчик раундов, золотые за победу и устроить настоящий рыцарский турнир :)) Затем можно взять Unity (там C# но он сильно похож😉) или libGTX java (там немного сложнее, но и прикольнее можно делать вещи😀), добавить спрайт-паки и сделать битву, но уже не консольную а графическую так сказать)).
Denis Odesskiy Уровень 47
3 мая 2024
/* Комментарий удален */
wokku Уровень 51
20 августа 2023
Главное в этой стратегии — упорядочивание, а не конкретно то, какой рыцарь (max или min) блокируется первым. Упорядочивание гарантирует, что в любой момент времени, при любом порядке вызова метода kill, блокировки всегда будут запрашиваться в одном и том же порядке. Если у нас есть два потока: Поток 1 вызывает kill(A, B) Поток 2 вызывает kill(B, A) Без упорядочивания могла бы возникнуть ситуация дедлока: поток 1 блокирует A и ждет B, в то время как поток 2 блокирует B и ждет A. С упорядочиванием, независимо от порядка передачи рыцарей в функцию, блокировки всегда запрашиваются в одной и той же последовательности (например, сначала рыцарь с наибольшим ID, затем с наименьшим). Это предотвращает возможный дедлок, потому что в любой момент времени только один поток может блокировать рыцаря с наибольшим ID, и другие потоки будут просто ждать.
Gans Electro Уровень 41
18 июля 2023
Не помню кто но у кого то была эта ссылка Игра Империя Тупиков
Михаил Уровень 32
20 декабря 2022
Узнал о JСonsole, которая позволяет увидеть дэдлок: Для Windows В Идее запускаем процесс, затем идем и ищем jconsole.jar с адресом типа C:\Program Files\Java\jdk1.8.0_301\lib\jconsole.jar двойной клик - из выпадающего списка выбираем наш процесс (например из задачи 2703 гастон и альфонс) Deadlock детектед.
Topsy Барбарисов Уровень 40
12 июля 2023
В поздних jdk ищите в папке C:\Program Files\Java\jdk-"версия jdk"\bin файл jconsole.exe
Ilya2710 Уровень 28
19 июля 2025
Еще вот эта штука то же самое делает, у неё интерфейс немного дружелюбнее "C:\Program Files\Java\jdk<версия jdk>\bin\jvisualvm.exe"
Ars Уровень 41
25 октября 2021
А что типа

try syncronized (o) {}
catch (LockedException e) {
  return "Object o locked, try later";
}
нет что ли? Должно быть подобное. Посмотрим.
28 июля 2022
насколько я понял, JVM не способна увидеть состояние DeadLock, какой код не пиши, во что не оборачивай. можно только предотвратить.
Kurama Уровень 50
12 ноября 2022
Так прикол тредов в том, что они не должны выбрасывать исключения, натыкаясь на syncronized Подобное бы поруинило кучу кода
Denis Odesskiy Уровень 47
3 мая 2024
В общем да, однако VisualVM (советую для изучения многопоточности) или JСonsole, или какая другая тулза профилирования, вполне себе способна.
Jh-007 Уровень 47
10 апреля 2021
Проще говоря, надо создать порядок в стохастическом процессе) Как на физкультуре: - Рыцари на первый-второй рассчитайсь! Первые номера бьют вторые, потом меняются.
Евгений Уровень 29
6 февраля 2021
пол часа разбирался что же это за неправильная лямда 😅

  Knight knightMax = knight1.id > knight2.id ? knight1: knight2;
  Knight knightMin = knight1.id > knight2.id ? knight2: knight1;
Макс Дудин Уровень 41
12 августа 2021
😂
Lyokha Blagodatskikh Уровень 48
24 декабря 2022
Аватарка в купе с комментарием прям топ )
Kex Уровень 38 Expert
1 июня 2020
https://javarush.com/groups/posts/1422-vzaimnaja-blokirovkadeadlock-v-java-i-metodih-borjhbih-s-neyhttps://javarush.com/groups/posts/1422-vzaimnaja-blokirovkadeadlock-v-java-i-metodih-borjhbih-s-ney в дополнение к прочтению о блокировках!
Кунг-Фу-Панда Уровень 36
3 сентября 2020
https://javarush.com/groups/posts/1422-vzaimnaja-blokirovkadeadlock-v-java-i-metodih-borjhbih-s-ney - лишняя ссылка у тебя приклеилась
Василий Бабин Уровень 3 Expert
17 октября 2020