[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-napishite-minimalnyy-neblokiruyushchiy-stek-vsego-dva-metoda-push-i-pop-s-ispolzovaniem-semaphore":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},288,"napishite-minimalnyy-neblokiruyushchiy-stek-vsego-dva-metoda-push-i-pop-s-ispolzovaniem-semaphore",8,"mnogopotochnost","Многопоточность","🔀","Напишите минимальный неблокирующий стек (всего два метода — push() и pop()) с использованием Semaphore","\u003C!-- grade: 4\u002F5 — корректно, но стоит отметить, что стек блокирующий, а не lock-free -->\n\nСтек с использованием `Semaphore` для управления доступом. Строго говоря, это **блокирующий** стек (семафор блокирует поток при захвате), а не lock-free, но он демонстрирует использование `Semaphore` как мьютекса (с одним permit).\n\n\u003Cdetails>\n\u003Csummary>Код: стек на Semaphore\u003C\u002Fsummary>\n\n```java\nclass SemaphoreStack\u003CT> {\n    private final Semaphore semaphore = new Semaphore(1);\n    private Node\u003CT> head = null;\n\n    SemaphoreStack\u003CT> push(T value) {\n        semaphore.acquireUninterruptibly();\n        try {\n            head = new Node\u003C>(value, head);\n        } finally {\n            semaphore.release();\n        }\n        return this;\n    }\n\n    T pop() {\n        semaphore.acquireUninterruptibly();\n        try {\n            Node\u003CT> current = head;\n            if (current != null) {\n                head = head.next;\n                return current.value;\n            }\n            return null;\n        } finally {\n            semaphore.release();\n        }\n    }\n\n    private static class Node\u003CE> {\n        private final E value;\n        private final Node\u003CE> next;\n\n        private Node(E value, Node\u003CE> next) {\n            this.value = value;\n            this.next = next;\n        }\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Отличие от lock-free версии:** здесь `Semaphore` с одним permit используется как мьютекс — только один поток может одновременно выполнять `push()` или `pop()`. В lock-free версии потоки не блокируют друг друга, а используют CAS-цикл.\n\n> **На собеседовании** стоит отметить, что `Semaphore(1)` — это не то же самое, что `ReentrantLock`: семафор не реентрабельный, и `release()` может вызвать любой поток. Также `acquireUninterruptibly()` выбран намеренно — он не бросает `InterruptedException`, упрощая API.","","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]