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

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

Ответ

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