Ответ
ReentrantLock — это реализация интерфейса Lock из пакета java.util.concurrent.locks, предоставляющая механизм взаимного исключения (mutex) с расширенными возможностями по сравнению с ключевым словом synchronized.
Ключевые особенности:
- Повторная входимость (Reentrancy): Поток, уже удерживающий блокировку, может захватить её повторно без взаимной блокировки (deadlock).
- Честность (Fairness): При создании можно указать политику честности (
fair). Честная блокировка (new ReentrantLock(true)) предоставляет доступ потокам в порядке FIFO, но снижает общую пропускную способность. - Прерываемое ожидание: Метод
lockInterruptibly()позволяет прервать поток, ожидающий блокировку. - Попытка захвата с таймаутом: Метод
tryLock(long timeout, TimeUnit unit)пытается получить блокировку в течение заданного времени.
Пример использования:
import java.util.concurrent.locks.ReentrantLock;
ReentrantLock lock = new ReentrantLock();
lock.lock(); // Захват блокировки
try {
// Критическая секция
sharedResource.modify();
} finally {
lock.unlock(); // Освобождение блокировки ВСЕГДА в finally-блоке
}
Сравнение с synchronized: |
Особенность | synchronized |
ReentrantLock |
|---|---|---|---|
| Поддержка tryLock | Нет | Да (с таймаутом) | |
| Честность | Нет (не гарантируется) | Да (опционально) | |
| Прерываемость | Нет (блокировка не прерывается) | Да (lockInterruptibly) |
|
| Условные переменные | Одно (wait/notify) |
Множество (Condition) |
|
| Синтаксис | Встроенное ключевое слово | Явный API, требует unlock в finally |
Когда использовать? ReentrantLock выбирают, когда необходимы продвинутые функции: неблокирующие попытки захвата (tryLock), честное планирование, работа с несколькими условиями ожидания (Condition) или необходимость прерываемого ожидания блокировки.