Для чего в Java используется ключевое слово synchronized?

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

Ответ

Ключевое слово synchronized в Java обеспечивает синхронизацию потоков, предотвращая состояние гонки (race condition) при доступе к общим ресурсам. Оно гарантирует, что только один поток в данный момент может выполнять синхронизированный блок кода или метод.

Основные способы применения:

  1. Синхронизированный метод: Блокирует весь объект (для нестатических методов) или класс (для статических).
    public synchronized void addToCounter(int value) {
        this.counter += value; // Потокобезопасная операция
    }
  2. Синхронизированный блок: Позволяет указать объект-монитор для блокировки, что повышает гибкость и производительность.

    private final Object lock = new Object();
    private List<String> items = new ArrayList<>();
    
    public void addItem(String item) {
        synchronized(lock) { // Блокируется только объект lock, а не весь this
            items.add(item);
        }
    }

    Важные замечания:

    • synchronized создает взаимную блокировку (mutual exclusion), которая может привести к взаимной блокировке (deadlock) при циклической зависимости блокировок.
    • Для сложных сценариев в пакете java.util.concurrent существуют более эффективные альтернативы: ReentrantLock, Semaphore, атомарные классы (AtomicInteger).