[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-napishite-minimalnyy-neblokiruyushchiy-stek-vsego-dva-metoda-push-i-pop":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":20,"progress":21,"seo":22},287,"napishite-minimalnyy-neblokiruyushchiy-stek-vsego-dva-metoda-push-i-pop",8,"mnogopotochnost","Многопоточность","🔀","Напишите минимальный неблокирующий стек (всего два метода — push() и pop())","\u003C!-- grade: 5\u002F5 — корректная lock-free реализация через CAS -->\n\nНеблокирующий (lock-free) стек реализуется с помощью `AtomicReference` и алгоритма compare-and-set (CAS). Ни один поток не блокирует другой — при конкуренции поток просто повторяет попытку.\n\n\u003Cdetails>\n\u003Csummary>Код: lock-free стек на AtomicReference\u003C\u002Fsummary>\n\n```java\nclass NonBlockingStack\u003CT> {\n    private final AtomicReference\u003CElement> head = new AtomicReference\u003C>(null);\n\n    NonBlockingStack\u003CT> push(final T value) {\n        final Element current = new Element();\n        current.value = value;\n        Element recent;\n        do {\n            recent = head.get();           \u002F\u002F Читаем текущую вершину\n            current.previous = recent;      \u002F\u002F Связываем новый элемент с текущей вершиной\n        } while (!head.compareAndSet(recent, current)); \u002F\u002F CAS: если вершина не изменилась — заменяем\n        return this;\n    }\n\n    T pop() {\n        Element result;\n        Element previous;\n        do {\n            result = head.get();            \u002F\u002F Читаем текущую вершину\n            if (result == null) {\n                return null;                \u002F\u002F Стек пуст\n            }\n            previous = result.previous;     \u002F\u002F Запоминаем предыдущий элемент\n        } while (!head.compareAndSet(result, previous)); \u002F\u002F CAS: если вершина не изменилась — удаляем\n        return result.value;\n    }\n\n    private class Element {\n        private T value;\n        private Element previous;\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Принцип работы CAS-цикла:**\n1. Поток читает текущее состояние.\n2. Подготавливает новое состояние.\n3. Атомарно пытается заменить старое на новое (`compareAndSet`).\n4. Если другой поток успел изменить состояние — CAS вернёт `false`, и цикл повторится.\n\nТакой подход гарантирует прогресс: хотя бы один поток всегда продвигается вперёд (lock-free гарантия).\n\n> **На собеседовании** могут спросить о проблеме ABA: если между чтением и CAS значение изменилось с A на B и обратно на A, CAS не заметит изменения. Для стека это обычно не критично, но в общем случае решается через `AtomicStampedReference`.","","senior",[15,16,17,18,19],"CAS","lock-free","неблокирующий-стек","AtomicReference","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":33,"featuredSnippetReady":34},"Неблокирующий стек на AtomicReference в Java — push и pop — Gymterview","Реализация lock-free стека на AtomicReference с методами push() и pop() через CAS-операцию compareAndSet. Пример кода с объяснением.","Минимальный неблокирующий стек в Java — AtomicReference + CAS","Lock-free стек с push() и pop() через AtomicReference.compareAndSet(). Потокобезопасная структура данных без блокировок.",[28,29,30,31,32],"неблокирующий стек Java","lock-free stack","AtomicReference стек","CAS compareAndSet","потокобезопасный стек","Неблокирующий стек реализуется через AtomicReference для хранения вершины стека. Методы push() и pop() используют цикл с compareAndSet (CAS): чтение текущей вершины, подготовка нового состояния и атомарная замена. Если другой поток изменил вершину — операция повторяется.",true]