Ответ
Lock — это интерфейс из пакета java.util.concurrent.locks, предоставляющий более гибкие и расширенные возможности для синхронизации потоков по сравнению с ключевым словом synchronized.
Ключевые реализации: ReentrantLock, ReentrantReadWriteLock.
Основные отличия Lock от synchronized:
| Характеристика | synchronized |
Lock (например, ReentrantLock) |
|---|---|---|
| Гибкость | Встроенное в язык, ограниченное. | Явный API с большим контролем. |
| Попытка захвата | Только блокировка с ожиданием. | Возможность попытки захвата с таймаутом (tryLock(long time, TimeUnit unit)). |
| Прерываемость | Не прерываемое ожидание. | Прерываемое ожидание (lockInterruptibly()). |
| Честность | Не гарантирует порядок (нечестный). | Может быть сконфигурирован как честный (fair lock). |
| Условия | Одно условие ожидания (wait/notify). | Поддержка множества условий (Condition). |
Пример использования ReentrantLock:
import java.util.concurrent.locks.*;
class Counter {
private final Lock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock(); // Захватываем блокировку
try {
count++;
} finally {
lock.unlock(); // Всегда освобождаем в finally
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
Когда использовать Lock: когда нужны расширенные функции (таймауты, честность, несколько условий). Когда использовать synchronized: для простых случаев, где его возможностей достаточно, так как это более лаконично и менее подвержено ошибкам (автоматическое освобождение).