Что такое интерфейс Lock в Java и чем он отличается от synchronized?

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

Ответ

java.util.concurrent.locks.Lock — это интерфейс, предоставляющий расширенный механизм управления блокировками для синхронизации потоков. Основная реализация — ReentrantLock.

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

Особенность synchronized Lock (например, ReentrantLock)
Способ управления Неявный (ключевое слово). Явный (вызов методов lock(), unlock()).
Попытка захвата с таймаутом Нет. Есть: tryLock(long time, TimeUnit unit).
Прерываемое ожидание Нет. Есть: lockInterruptibly().
Честность (fairness) Не гарантируется. Можно создать честную блокировку (new ReentrantLock(true)).
Условные переменные Одна (wait(), notify(), notifyAll()). Множественные (Condition на один Lock).

Базовый шаблон использования Lock:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

Lock lock = new ReentrantLock();
// ...
lock.lock(); // Захват блокировки
try {
    // Критическая секция — доступ к общему ресурсу
    sharedResource.modify();
} finally {
    lock.unlock(); // ВСЕГДА освобождайте блокировку в finally-блоке!
}

Пример с tryLock() (избегание deadlock):

if (lock1.tryLock()) {
    try {
        if (lock2.tryLock()) {
            try {
                // Работа с двумя ресурсами
            } finally { lock2.unlock(); }
        }
    } finally { lock1.unlock(); }
}
// Если не удалось захватить обе блокировки, можно повторить попытку или выполнить альтернативную логику.

Когда использовать Lock:

  • Требуется гибкость: таймауты, прерывания, чередование блокировок.
  • Нужны несколько очередей ожидания (Condition).
  • Логика синхронизации сложнее, чем простая блокировка метода/блока.

Когда использовать synchronized:

  • Простые случаи синхронизации.
  • Приоритет — читаемость и минимализм кода.
  • Встроенная поддержка JVM (оптимизации, например, biased locking).