Ответ
Синхронизация потоков — это механизм координации доступа нескольких потоков к общим ресурсам (переменным, объектам, файлам) для предотвращения состояний гонки (race condition) и обеспечения согласованности данных.
Без синхронизации параллельные операции чтения/записи могут привести к потере обновлений, чтению некорректных промежуточных состояний или другим недетерминированным ошибкам.
Основные механизмы синхронизации в Java:
-
Ключевое слово
synchronized(монитор объекта/класса):public class SynchronizedCounter { private int count = 0; // Синхронизированный метод (монитор — this) public synchronized void increment() { count++; // Операция "чтение-изменение-запись" теперь атомарна } // Синхронизированный блок public void decrement() { synchronized (this) { // Явное указание монитора count--; } } } -
Блокировки из пакета
java.util.concurrent.locks(более гибкие):import java.util.concurrent.locks.ReentrantLock; public class LockCounter { private int count = 0; private final ReentrantLock lock = new ReentrantLock(); public void increment() { lock.lock(); // Захватываем блокировку try { count++; } finally { lock.unlock(); // Всегда освобождаем в finally! } } } -
Атомарные классы (
java.util.concurrent.atomic) для простых операций:import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // Атомарная операция без явных блокировок } }
Ключевые концепции:
- Взаимное исключение (Mutual Exclusion): Только один поток может выполнять критическую секцию.
- Видимость (Visibility): Изменения, сделанные одним потоком в синхронизированном блоке, гарантированно видны другому потоку, входящему в синхронизированный блок по тому же монитору (решается через отношение happens-before).
Важно: Синхронизация может приводить к взаимным блокировкам (deadlock) и снижению производительности, поэтому ее следует применять минимально и обдуманно.