Sobes.tech
Назад к вопросам
Senior
7

Как боролись с deadlock при пессимистичной блокировке?

Компании, где спрашивали
прайм пейментс

Ответ от нейросети

sobes.tech AI

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

Основные подходы для борьбы с deadlock:

  1. Избегание циклов в порядке захвата блокировок — всегда захватывать блокировки в одном и том же порядке, чтобы исключить циклические ожидания.

  2. Установка таймаутов на блокировки — если поток не может получить блокировку за определённое время, он освобождает уже захваченные ресурсы и повторяет попытку позже.

  3. Обнаружение и откат — система отслеживает состояние блокировок, обнаруживает циклы и прерывает одну из транзакций, чтобы разорвать deadlock.

  4. Использование tryLock с повторными попытками — в Java можно использовать метод tryLock() из java.util.concurrent.locks.Lock, который пытается захватить блокировку без блокировки потока, и при неудаче можно освободить уже захваченные блокировки и повторить попытку.

Пример с использованием tryLock:

Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();

boolean acquireLocks(Lock firstLock, Lock secondLock) {
    boolean gotFirst = false;
    boolean gotSecond = false;
    try {
        gotFirst = firstLock.tryLock();
        gotSecond = secondLock.tryLock();
    } finally {
        if (!(gotFirst && gotSecond)) {
            if (gotFirst) firstLock.unlock();
            if (gotSecond) secondLock.unlock();
        }
    }
    return gotFirst && gotSecond;
}

// Вызов в потоке
while (!acquireLocks(lock1, lock2)) {
    // ждем или делаем паузу, затем повторяем
}
// критическая секция
lock2.unlock();
lock1.unlock();

Таким образом, при невозможности захватить все необходимые блокировки одновременно, поток освобождает уже захваченные и повторяет попытку, что предотвращает deadlock.