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

Что такое Livelock в Java

1️⃣ Как кратко ответить

Livelock в Java — это ситуация, когда два или более потоков постоянно меняют свои состояния в ответ на действия друг друга, но ни один из них не может продвинуться к завершению задачи. Это похоже на deadlock, но в случае livelock потоки не блокируются, а продолжают работать, не достигая прогресса.

2️⃣ Подробное объяснение темы

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

Зачем это нужно знать?

Понимание livelock важно для разработки надежных многопоточных приложений. Если не учитывать возможность livelock, приложение может застрять в бесконечном цикле, что приведет к потере производительности и ресурсов.

Как это работает?

Livelock возникает, когда потоки постоянно реагируют на действия друг друга, но не могут завершить свои задачи. В отличие от deadlock, где потоки блокируются и не могут продолжать работу, в livelock потоки продолжают работать, но без прогресса.

Пример кода

Рассмотрим пример, где два потока пытаются выполнить задачу, но постоянно меняют свои состояния в ответ на действия друг друга:

class Resource {
    private boolean isLocked = false;
​
    public synchronized void lock() {
        while (isLocked) {
            // Поток ждет, пока ресурс не будет разблокирован
            Thread.yield();
        }
        isLocked = true;
    }
​
    public synchronized void unlock() {
        isLocked = false;
    }
}
​
public class LivelockExample {
    public static void main(String[] args) {
        final Resource resource1 = new Resource();
        final Resource resource2 = new Resource();
​
        Thread thread1 = new Thread(() -> {
            while (true) {
                resource1.lock();
                if (!resource2.isLocked) {
                    resource2.lock();
                    // Выполнение задачи
                    resource2.unlock();
                    resource1.unlock();
                    break;
                } else {
                    resource1.unlock();
                }
            }
        });
​
        Thread thread2 = new Thread(() -> {
            while (true) {
                resource2.lock();
                if (!resource1.isLocked) {
                    resource1.lock();
                    // Выполнение задачи
                    resource1.unlock();
                    resource2.unlock();
                    break;
                } else {
                    resource2.unlock();
                }
            }
        });
​
        thread1.start();
        thread2.start();
    }
}

Объяснение кода:

  • Класс Resource:

    • Переменная isLocked указывает, заблокирован ли ресурс.
    • Метод lock() блокирует ресурс, если он не заблокирован, иначе поток ждет.
    • Метод unlock() разблокирует ресурс.
  • Класс LivelockExample:

    • Создаются два ресурса resource1 и resource2.
    • thread1:
      • Пытается заблокировать resource1.
      • Если resource2 не заблокирован, блокирует его и выполняет задачу.
      • Если resource2 заблокирован, разблокирует resource1 и повторяет попытку.
    • thread2:
      • Пытается заблокировать resource2.
      • Если resource1 не заблокирован, блокирует его и выполняет задачу.
      • Если resource1 заблокирован, разблокирует resource2 и повторяет попытку.

В этом примере потоки могут постоянно разблокировать и блокировать ресурсы, не продвигаясь к выполнению задачи, что и является livelock.

Тема: Многопоточность
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки