Какие знаешь способы предотвращения Deadlock

«Какие знаешь способы предотвращения Deadlock» — вопрос из категории Многопоточность, который задают на 23% собеседований Android Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Deadlock возникает, когда потоки взаимно блокируют друг друга, ожидая освобождения ресурсов. Основные способы предотвращения:

  1. Упорядоченное получение блокировок
    Всегда захватывать блокировки в одинаковом порядке. Например:
// Правильно:
synchronized(lockA) {
    synchronized(lockB) { ... }
}

// Опасно:
synchronized(lockB) {
    synchronized(lockA) { ... } // может привести к deadlock
}
  1. Использование таймаутов
    Применять tryLock() с таймаутом вместо блокирующих вызовов:
if (lockA.tryLock(100, TimeUnit.MILLISECONDS)) {
    try {
        if (lockB.tryLock(100, TimeUnit.MILLISECONDS)) {
            // работа с ресурсами
        }
    } finally {
        lockB.unlock()
        lockA.unlock()
    }
}
  1. Избегание вложенных блокировок
    Рефакторинг кода для уменьшения областей синхронизации.

  2. Использование атомарных операций
    Замена блокировок на Atomic-классы где возможно.

  3. Анализ зависимостей
    Выявление циклических зависимостей между потоками на этапе проектирования.