Какие средства кроме конкурирующих коллекций используются для синхронизации потоков
Что проверяют
Знаете ли вы уровни синхронизации от ключевого слова до высокоуровневых классов и умеете ли выбирать по задаче, а не по привычке. Вопрос обычно идёт вторым, после конкурентных коллекций, и проверяет ширину. Следом уточняют, чем ReentrantLock лучше synchronized и что на самом деле даёт volatile.
Как отвечать
Двигайтесь по уровням:
synchronizedиwait/notify: монитор объекта, реентерабельность, автоматическое освобождение при исключении. Нет таймаута, нет прерывания, нет попытки захвата;volatile: видимость изменений и запрет переупорядочивания, но не атомарность операции чтение-изменение-запись;java.util.concurrent.atomic:AtomicInteger,AtomicReferenceи цикл CAS,LongAdderдля счётчиков под высокой конкуренцией;ReentrantLock:tryLockс таймаутом,lockInterruptibly, честный режим, несколько объектовConditionна один замок. Освобождение только вfinally;ReentrantReadWriteLockиStampedLock: второй даёт оптимистичное чтение черезtryOptimisticReadиvalidate, но он не реентерабельный и не поддерживает условия;- координация:
CountDownLatch(одноразовый),CyclicBarrier(переиспользуемый),Phaser(фазы с изменяемым числом участников),Semaphore(ограничение пропускной способности),Exchanger; - уровень задач:
ExecutorService,CompletableFuture,ForkJoinPool. Часто правильный ответ вообще не замок, а очередь и один владелец состояния.
Добавьте современный контекст: с JDK 21 есть виртуальные потоки, и в JDK 24 блок synchronized перестал закреплять виртуальный поток за несущим, так что старый совет «в виртуальных потоках только ReentrantLock» уже неактуален. Передачу контекста вместо ThreadLocal в JDK 25 закрывает ScopedValue.
Где спотыкаются
Синхронизируются по изменяемому полю или по String и Integer из кэша. В первом случае замок теряется при переприсваивании, во втором он неожиданно общий на всю JVM.
Считают, что volatile делает i++ безопасным. Это три операции, и volatile их не склеивает.
Держат замок на время похода в сеть или в базу, а деградацию под нагрузкой объясняют медленным внешним сервисом.