Ответ
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 недостаточно (например, при необходимости чередования потоков, таймаутов или неблокирующих попыток захвата).