[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-v-chyom-zaklyuchayutsya-razlichiya-mezhdu-java-util-concurrent-atomic-compareandswap-i-java-util-concurrent-atomic-weakcompareandswap":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":21,"progress":22,"seo":23},251,"v-chyom-zaklyuchayutsya-razlichiya-mezhdu-java-util-concurrent-atomic-compareandswap-i-java-util-concurrent-atomic-weakcompareandswap",8,"mnogopotochnost","Многопоточность","🔀","В чём заключаются различия между java.util.concurrent.Atomic*.compareAndSwap() и java.util.concurrent.Atomic*.weakCompareAndSwap()","\u003C!-- grade: 3\u002F5 — перечислены различия, но нет контекста применения и нет примера -->\n\nНачиная с Java 9, методы были переименованы: `compareAndSet()` (сильная версия) и `weakCompareAndSetPlain()` \u002F `weakCompareAndSetAcquire()` \u002F `weakCompareAndSetRelease()` \u002F `weakCompareAndSetVolatile()` (слабые версии с разной семантикой упорядочивания памяти).\n\n### Основные различия\n\n| Характеристика | `compareAndSet()` (сильный CAS) | `weakCompareAndSet*()` (слабый CAS) |\n|---|---|---|\n| Гарантия успеха | Если текущее значение совпадает с ожидаемым -- всегда обновит | Может **спонтанно вернуть `false`** даже при совпадении значений |\n| Memory barrier | Создаёт полный барьер памяти, обеспечивает happens-before | В зависимости от варианта: `Plain` -- без барьера, `Acquire`\u002F`Release`\u002F`Volatile` -- с соответствующим барьером |\n| Производительность | Чуть дороже из-за барьеров и гарантий | На некоторых архитектурах (ARM, PowerPC) может быть быстрее |\n| Применение | Универсальное: одиночные CAS-операции | Только внутри циклов повтора, где спонтанный `false` не страшен |\n\n### Почему слабый CAS может вернуть false без причины\n\nНа архитектурах с LL\u002FSC (Load-Linked \u002F Store-Conditional), таких как ARM и RISC-V, CAS реализуется через пару инструкций. Между `LL` и `SC` может произойти «ложная инвалидация» кэш-линии (например, из-за переключения контекста или записи в соседнюю переменную той же кэш-линии), и `SC` завершится неудачей, хотя значение не менялось. Сильный CAS компенсирует это циклом повтора внутри себя; слабый -- нет.\n\n### Когда использовать слабый CAS\n\nСлабый CAS оправдан, когда:\n- операция уже находится в цикле повтора (retry loop), и дополнительная итерация обходится дёшево;\n- не нужна полная семантика happens-before (используется `weakCompareAndSetPlain()`);\n- критична максимальная производительность на архитектурах LL\u002FSC.\n\n\u003Cdetails>\n\u003Csummary>Пример: использование weakCompareAndSetVolatile() в цикле\u003C\u002Fsummary>\n\n```java\n\u002F\u002F Потокобезопасный инкремент с использованием слабого CAS\n\u002F\u002F (иллюстрация -- для реальных счётчиков используйте AtomicInteger.incrementAndGet())\npublic static int weakIncrement(AtomicInteger counter) {\n    int current;\n    do {\n        current = counter.get();\n    } while (!counter.weakCompareAndSetVolatile(current, current + 1));\n    \u002F\u002F Спонтанный false просто приведёт к ещё одной итерации цикла\n    return current + 1;\n}\n```\n\n\u003C\u002Fdetails>\n\n> **Аналогия из жизни.** Представьте автомат по продаже напитков. Сильный CAS -- это надёжный автомат: если монета вставлена правильно, напиток всегда выдаётся. Слабый CAS -- это капризный автомат: иногда он возвращает монету без причины, и нужно вставить её повторно. Если вы уже стоите у автомата и готовы повторить -- капризный автомат не проблема, зато он может работать чуть быстрее.\n\n> **На собеседовании.** Этот вопрос проверяет глубину знания низкоуровневых механизмов. Если вас просят сравнить -- обязательно упомяните: (1) спонтанный `false` у слабого CAS, (2) различия в memory barriers, (3) зависимость от архитектуры процессора (LL\u002FSC vs x86). На x86 разницы в производительности практически нет, потому что CAS реализуется одной инструкцией `CMPXCHG`.","","senior",[15,16,17,18,19,20],"CAS","compareAndSwap","Atomic","memory barrier","weakCompareAndSwap","concurrency",[],null,{"title":24,"description":25,"ogTitle":26,"ogDescription":27,"keywords":28,"schemaAnswer":33,"featuredSnippetReady":34},"compareAndSwap vs weakCompareAndSwap в Java — Gymterview","weakCompareAndSwap не создаёт memory barrier, не гарантирует happens-before и может вернуть false без причины. Более лёгкая, но менее надёжная операция.","compareAndSwap vs weakCompareAndSwap — 3 ключевых отличия","weakCompareAndSwap не создаёт memory barrier, зависит от кэша CPU и может ложно вернуть false. Поддерживается не всеми архитектурами.",[29,30,31,32],"compareAndSwap Java","weakCompareAndSwap Java","CAS weak Java","memory barrier Atomic","weakCompareAndSwap() не создаёт memory barrier и не даёт гарантии happens-before. Она зависит от кэша\u002FCPU и может вернуть false без видимых причин. Это более лёгкая операция, но поддерживаемая не всеми архитектурами и не всегда эффективная.",true]