Ответ
Преимущества:
- Простота использования: Встроенная в язык конструкция. Для базовой синхронизации достаточно добавить ключевое слово к методу или блоку.
- Автоматическое управление блокировкой: JVM гарантирует захват и освобождение монитора, что предотвращает утечку блокировок.
- Гарантия видимости изменений (happens-before): Запись в память, выполненная одним потоком в
synchronized-блоке, гарантированно видна другому потоку, который входит вsynchronized-блок для того же объекта-монитора.
Недостатки:
- Грубая блокировка: Блокирует весь объект (для методов экземпляра) или весь класс (для статических методов), даже если конфликтующий доступ происходит только к части данных.
- Отсутствие расширенного функционала: Невозможно попытаться захватить блокировку (
tryLock), задать время ожидания или создать условия (Condition) для более сложной координации потоков. - Риск взаимоблокировки (deadlock): При неправильном порядке захвата нескольких блокировок.
- Производительность: В высококонкурентных сценариях может стать узким местом из-за contention (состязания потоков за монитор).
Пример и альтернативы:
// Простой пример с synchronized
public class Counter {
private int count = 0;
public synchronized void increment() {
count++; // Операция атомарна и потокобезопасна
}
}
// Альтернативы для разных случаев:
// 1. java.util.concurrent.atomic.AtomicInteger - для одиночных переменных
// 2. java.util.concurrent.locks.ReentrantLock - для гибкой блокировки с tryLock, таймаутами
// 3. java.util.concurrent.locks.StampedLock - оптимистичные блокировки для read-heavy сценариев
// 4. Неблокирующие алгоритмы (CAS-операции)