Ответ
synchronized блок используется для обеспечения взаимного исключения (mutual exclusion) при доступе к общему ресурсу (разделяемому состоянию) из нескольких потоков. Он гарантирует, что только один поток может выполнить защищенный участок кода в данный момент.
Основные сценарии:
- Защита критической секции: Когда несколько потоков изменяют общие изменяемые данные.
- Обеспечение видимости изменений: Гарантирует, что изменения, сделанные одним потоком, будут видны другому (реализует happens-before).
Пример защиты общего счетчика:
public class ThreadSafeCounter {
private int value = 0;
private final Object lock = new Object(); // Специальный объект-монитор
public void increment() {
synchronized (lock) { // Блокировка по объекту lock
value++; // Критическая секция защищена
}
}
public int getValue() {
synchronized (lock) { // Чтение также должно быть синхронизировано
return value;
}
}
}
Преимущества synchronized блока перед synchronized методом:
- Гибкость: Можно синхронизировать не весь метод, а только критическую секцию, уменьшая contention.
- Контроль над монитором: Можно использовать отдельный объект (
private final Object lock) вместоthis, что безопаснее и предотвращает внешнюю блокировку.
Современные альтернативы: Для более сложных сценариев рассмотрите java.util.concurrent.locks.ReentrantLock (с поддержкой таймаутов, прерываний) или атомарные классы (AtomicInteger).