← Назад к вопросам

Что такое LiveLock?

1.3 Junior🔥 142 комментариев
#Асинхронность

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое LiveLock?

Livelock - это состояние, когда один или несколько потоков (threads) находятся в активном состоянии, но не могут прогрессировать в выполнении из-за взаимного взаимодействия. В отличие от deadlock, потоки здесь не заблокированы, они активно выполняют код, но полезной работы не происходит.

Основная разница между Deadlock и LiveLock

Deadlock: Потоки заблокированы и ждут друг друга - ничего не происходит. LiveLock: Потоки активны, выполняют код, но их действия противоречат друг другу - прогресса нет.

Пример LiveLock в Dart/Flutter

class Account {
  int balance = 0;
  
  Future<void> transfer(Account other, int amount) async {
    while (true) {
      if (this.balance >= amount) {
        if (other.balance == 0) {
          this.balance -= amount;
          other.balance += amount;
          print("Transfer successful");
          break;
        } else {
          // Уступаем другому потоку
          await Future.delayed(Duration(milliseconds: 1));
        }
      }
    }
  }
}

Здесь оба потока переводов могут бесконечно уступать друг другу, проверяя условие, но ничего не переводя.

Классический пример: два столовых прибора

Два философа пытаются взять две вилки. Вилки расположены между ними. Если оба одновременно берут одну вилку и видят, что вторая занята, они оба кладут вилку обратно и ждут. Потом снова берут и снова видят занятую. Это livelock - оба активны, но прогресса нет.

Как избежать LiveLock

1. Добавить случайную задержку:

Future<void> transferWithBackoff(Account other, int amount) async {
  final random = Random();
  
  while (true) {
    if (this.balance >= amount) {
      if (other.balance == 0) {
        this.balance -= amount;
        other.balance += amount;
        break;
      } else {
        // Случайная задержка вместо фиксированной
        await Future.delayed(
          Duration(milliseconds: random.nextInt(100))
        );
      }
    }
  }
}

2. Установить приоритеты:

future<void> transferWithPriority(
  Account other,
  int amount,
  int priority,
) async {
  while (true) {
    if (this.balance >= amount && other.balance == 0) {
      if (this.hashCode < other.hashCode || priority > other.priority) {
        this.balance -= amount;
        other.balance += amount;
        break;
      }
    }
    await Future.delayed(Duration(milliseconds: 10));
  }
}

3. Использовать очереди и mutex:

Использование Mutex из пакета synchronized для правильной синхронизации:

import "package:synchronized/synchronized.dart";

class Account {
  final _lock = Lock();
  int balance = 0;
  
  Future<void> safeTransfer(Account other, int amount) async {
    await _lock.synchronized(() async {
      if (this.balance >= amount) {
        this.balance -= amount;
        other.balance += amount;
      }
    });
  }
}

Признаки LiveLock в Flutter приложении

  • Приложение не зависает полностью, но не реагирует на действия
  • Потребление CPU остается высоким
  • Нет явного deadlock, но функционал работает неправильно
  • В логах может быть видна постоянная переактивация одного и того же кода

Практические совет

  1. Избегайте цикла, который постоянно проверяет условие
  2. Используйте правильные примитивы синхронизации (Mutex, Semaphore)
  3. Добавляйте экспоненциальный backoff вместо фиксированных задержек
  4. Устанавливайте приоритеты между конкурирующими ресурсами
  5. Тестируйте многопоточный код под нагрузкой

Livelock - это более тонкая проблема, чем deadlock, и требует более внимательного анализа и тестирования.

Что такое LiveLock? | PrepBro