— Привіт, Аміго!
Хочу розповісти тобі про декілька стратегій уникання дедлоків.
Найкраща стратегія – це продумана архітектура й набір правил щодо того, коли можна використовувати блокування (захопленя м'ютексів) та в якому порядку. Класичний спосіб боротьби з проблемою — розробка ієрархії блокувань, встановлення правила, що деякі блокування ніколи не можуть бути захопленими в стані, в якому вже захоплено якісь інші блокування.
Інколи, наприклад, блокуванням присвоюють рівні, і водночас вимагають від потоку захоплювати блокування в порядку від більшого рівня до меншого, але не в зворотному. Також не можна захоплювати кілька блокувань одного рівня.
Давай згадаємо попередній приклад про лицарів. Кожному лицарю можна додати унікальний номер (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;
}
}
}
}
— Гарне рішення.
— Це дуже просте рішення, але мені воно подобається. Сподіваюся, воно тобі стане у пригоді, коли будеш думати, яким чином краще вирішити можливі проблеми з дедлоками.
— Дякую.