Вопрос объясняет методы предотвращения взаимных блокировок в многопоточной среде.
Избегайте вложенных блокировок.
Используйте таймауты (например, tryLock(timeout)).
Упорядочивайте блокировки (всегда получайте lockA перед lockB).
Возникает, когда потоки блокируют друг друга, ожидая ресурсы.
Способы избежать:
Упорядочивание блокировок:
Всегда получайте блокировки в одинаковом порядке.
// Правильно: lockA -> lockB
synchronized(lockA) {
synchronized(lockB) { ... }
}Таймауты:
Используйте tryLock с таймаутом.
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try { /* работа */ }
finally { lock.unlock() }
}Потоки постоянно меняют состояние, но не прогрессируют.
Пример:
// Два потока "вежливо" уступают друг другу
while (!acquireLock()) {
Thread.yield() // Livelock!
}Решение:
Добавьте случайные задержки (Thread.sleep(randomDelay)).
Вывод:
Планируйте блокировки заранее и используйте таймауты.