Создание примера гарантированного взаимоблокировки

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

Короткий ответ

Что ответить на собеседовании

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

Подробный разбор

Ответ с пояснениями

Условие

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

Ответ

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

Object a = new Object(), b = new Object();
var barrier = new java.util.concurrent.CyclicBarrier(2);
Runnable first = () -> lockBoth(a, b, barrier);
Runnable second = () -> lockBoth(b, a, barrier);
new Thread(first).start();
new Thread(second).start();

Вспомогательный метод:

static void lockBoth(Object first, Object second,
                     java.util.concurrent.CyclicBarrier barrier) {
    synchronized (first) {
        try { barrier.await(); }
        catch (Exception e) { throw new RuntimeException(e); }
        synchronized (second) { System.out.println("Unreachable"); }
    }
}

При нормальном запуске обоих потоков без прерывания барьера deadlock не зависит от sleep и случайного тайминга. Это намеренно зависающий учебный пример, запускаемый только изолированно. Исправление — единый порядок захвата a, затем b.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее