Ответ
В многопоточном программировании на Java распространены следующие проблемы синхронизации:
1. Состояние гонки (Race Condition) Возникает, когда несколько потоков одновременно изменяют общие данные, и результат зависит от порядка их выполнения.
public class Counter {
private int count = 0;
// Без синхронизации инкременты могут "потеряться"
public synchronized void increment() { // synchronized решает проблему
count++;
}
}
2. Взаимная блокировка (Deadlock) Два или более потока бесконечно ждут друг друга, удерживая нужные друг другу блокировки.
// Поток 1: synchronized(resourceA) { wait for resourceB }
// Поток 2: synchronized(resourceB) { wait for resourceA }
3. Активная блокировка (Livelock) Потоки постоянно меняют своё состояние в ответ на действия друг друга, но не могут продвинуться в выполнении полезной работы (аналог "вежливой" взаимной уступки).
4. Голодание (Starvation) Поток долго не может получить доступ к общему ресурсу, потому что другие потоки (с более высоким приоритетом или частые) постоянно его монополизируют.
Инструменты для решения:
- Ключевое слово
synchronized(методы, блоки). - Классы из пакета
java.util.concurrent:Lock,Semaphore,CountDownLatch,CyclicBarrier. - Атомарные классы (
AtomicInteger,AtomicReferenceи др.) для lock-free операций. - Неизменяемые (immutable) объекты — самый безопасный способ избежать синхронизации.
- Потокобезопасные коллекции (
ConcurrentHashMap,CopyOnWriteArrayList).