[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-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},279,"chto-takoe-semaphore",8,"mnogopotochnost","Многопоточность","🔀","Что такое Semaphore?","\u003C!-- grade: 3\u002F5 — очень краткий; добавлены примеры, пояснение fair\u002Funfair, таблица -->\n\n`Semaphore` — это синхронизатор из пакета `java.util.concurrent`, реализующий классический **счётный семафор**. Он управляет доступом к ограниченному числу ресурсов через внутренний счётчик разрешений (permits).\n\n**Принцип работы:**\n- При создании задаётся начальное количество разрешений.\n- `acquire()` — поток запрашивает разрешение. Если счётчик > 0, он уменьшается на 1 и поток проходит. Если счётчик = 0, поток блокируется до появления свободного разрешения.\n- `release()` — поток возвращает разрешение, увеличивая счётчик на 1. Если есть ожидающие потоки, один из них разблокируется.\n\n**Пример — ограничение одновременных подключений к БД:**\n\n\u003Cdetails>\n\u003Csummary>Код: пул подключений через Semaphore\u003C\u002Fsummary>\n\n```java\nclass ConnectionPool {\n    private final Semaphore semaphore;\n    private final BlockingQueue\u003CConnection> pool;\n\n    ConnectionPool(int maxConnections) {\n        this.semaphore = new Semaphore(maxConnections, true); \u002F\u002F fair\n        this.pool = new LinkedBlockingQueue\u003C>();\n        for (int i = 0; i \u003C maxConnections; i++) {\n            pool.add(createConnection());\n        }\n    }\n\n    Connection acquire() throws InterruptedException {\n        semaphore.acquire(); \u002F\u002F Ждём, если все разрешения заняты\n        return pool.poll();\n    }\n\n    void release(Connection conn) {\n        pool.offer(conn);\n        semaphore.release(); \u002F\u002F Возвращаем разрешение\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Основные методы:**\n\n| Метод | Описание |\n|---|---|\n| `acquire()` | Захватить одно разрешение (блокирующий) |\n| `acquire(int n)` | Захватить n разрешений |\n| `tryAcquire()` | Попытаться захватить без блокировки |\n| `tryAcquire(time, unit)` | Попытаться с таймаутом |\n| `release()` | Освободить одно разрешение |\n| `availablePermits()` | Текущее количество свободных разрешений |\n| `drainPermits()` | Забрать все доступные разрешения |\n\n**Fair vs Unfair.** Конструктор `new Semaphore(permits, true)` создаёт «честный» семафор — потоки получают разрешения в порядке очереди (FIFO). По умолчанию семафор «нечестный» — это быстрее, но потоки могут получить разрешение вне очереди.\n\n**Бинарный семафор (permits = 1)** — по поведению похож на мьютекс, но с важным отличием: семафор не имеет понятия «владелец» — `release()` может вызвать любой поток, не только тот, кто вызвал `acquire()`. Это отличает его от `ReentrantLock`, где `unlock()` может вызвать только поток-владелец.\n\n> **Аналогия:** семафор — это парковка с ограниченным числом мест. На въезде стоит счётчик свободных мест. Когда машина заезжает — счётчик уменьшается. Когда выезжает — увеличивается. Если мест нет (счётчик = 0), новые машины ждут у шлагбаума.\n\n> **На собеседовании** могут спросить: «Чем `Semaphore` с одним permit отличается от `ReentrantLock`?» Ключевые отличия: семафор не реентрабельный (повторный `acquire()` из того же потока заблокирует его), и `release()` может вызвать любой поток.","","middle",[15,16,17,18,19],"ограничение-доступа","счётчик","синхронизатор","Semaphore","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":32,"featuredSnippetReady":33},"Что такое Semaphore в Java — семафор со счётчиком — Gymterview","Semaphore — синхронизатор с счётчиком: поток уменьшает счётчик при входе и увеличивает при выходе. При нуле — блокировка. Используется для ограничения доступа к ресурсам.","Semaphore в Java — управление доступом к ограниченным ресурсам","Semaphore управляет доступом через счётчик: при нуле поток блокируется. Применяется для защиты дорогих ресурсов, например подключений к БД.",[28,29,17,30,31],"Semaphore Java","семафор Java","ограничение доступа к ресурсу","пул подключений","Semaphore — синхронизатор, реализующий шаблон Семафор. Доступ управляется счётчиком: при входе потока в блок кода счётчик уменьшается, при выходе — увеличивается. Если счётчик равен нулю, поток блокируется. Используется для защиты ресурсов, доступных в ограниченном количестве, например подключений к БД в пуле.",true]