Ответ
Ключевое слово synchronized обеспечивает синхронизацию потоков на уровне монитора объекта или класса. Его основные характеристики:
1. Взаимное исключение (Mutual Exclusion): Гарантирует, что только один поток может выполнять синхронизированный блок кода для данного монитора в один момент времени.
2. Видимость изменений (Memory Visibility): Создает отношение «происходит-до» (happens-before). Все изменения переменных, сделанные потоком перед выходом из синхронизированного блока, становятся видимыми следующему потоку, который захватит тот же монитор.
3. Повторная входимость (Reentrancy): Поток, уже владеющий монитором, может повторно войти в любой блок, синхронизированный по тому же монитору. Это предотвращает самоблокировку (self-deadlock).
4. Монитор:
- Для нестатических методов и блоков кода монитором выступает объект (
this). - Для статических методов и блоков
synchronized(Class.class)монитором выступает объект класса (Class).
Примеры использования:
// Синхронизированный метод (монитор = this)
public synchronized void addToCounter(int value) {
this.count += value;
}
// Синхронизированный блок с явным указанием монитора
public void updateValue(String key, Object value) {
synchronized (this.lockObject) { // Используется отдельный объект для блокировки
this.cache.put(key, value);
}
}
// Синхронизированный статический метод (монитор = Class object)
public static synchronized int getGlobalCount() {
return globalCount;
}
Недостатки и альтернативы:
- Производительность: Избыточная синхронизация может стать узким местом.
- Дедлоки: Неправильный порядок захвата мониторов может привести к взаимной блокировке.
- Альтернативы: Для более гибкого управления блокировками используйте
java.util.concurrent.locks.ReentrantLock. Для атомарных операций — классы изjava.util.concurrent.atomic(например,AtomicInteger).