Что такое ReentrantLock в Java?

«Что такое ReentrantLock в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

ReentrantLock — это реализация интерфейса Lock, предоставляющая механизм взаимного исключения (mutex) с расширенными возможностями по сравнению с synchronized.

Ключевые преимущества перед synchronized:

  • Явное управление: блокировка (lock()) и разблокировка (unlock()) контролируются вручную.
  • Попытка захвата с таймаутом: tryLock(long timeout, TimeUnit unit).
  • Прерываемое ожидание: lockInterruptibly().
  • Честность (fairness): можно создать lock с политикой fair, которая гарантирует предоставление блокировки самому долго ожидающему потоку.
  • Возможность проверки: методы isLocked(), isHeldByCurrentThread().

Пример безопасного использования:

ReentrantLock lock = new ReentrantLock();
lock.lock(); // Захватываем блокировку
try {
    // Критическая секция
    // ... доступ к общим ресурсам
} finally {
    lock.unlock(); // Всегда освобождаем в finally-блоке
}

Важное свойство: Как и synchronized, ReentrantLock является реентерабельным (reentrant) — один и тот же поток может захватить одну и ту же блокировку несколько раз.

Когда использовать? В сложных сценариях, где возможностей synchronized недостаточно (например, при необходимости чередования потоков, таймаутов или неблокирующих попыток захвата).