Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗ktSpSySm 171 of 299 menu
◀ ▶

Семафор в Kotlin

Семафор считает, сколько корутин одновременно могут войти в участок. У Semaphore из kotlinx.coroutines.sync задают начальное число разрешений в конструкторе.

Функция acquire забирает одно разрешение и при нуле приостанавливает корутину. Функция release возвращает разрешение ожидающим. Снятие в finally повторяет правило замка:

import kotlinx.coroutines.sync.Semaphore val lane = Semaphore(2) suspend fun enter() { lane.acquire() try { println("inside") } finally { lane.release() } }

Два разрешения означают, что третья корутина останется ждать, пока кто-то не вызовет release. Три задачи по очереди проходят короткий участок:

import kotlinx.coroutines.delay import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Semaphore fun main() { runBlocking { val lane = Semaphore(2) val jobs = List(3) { id -> launch { lane.acquire() try { println("start $id") delay(50) println("end $id") } finally { lane.release() } } } joinAll(*jobs.toTypedArray()) } }

Счетчик активных гостей удобно держать рядом с семафором: под acquire увеличивают, под release уменьшают. Так видно, что одновременно внутри не больше двух:

import kotlinx.coroutines.sync.Semaphore class Hall(private val lane: Semaphore = Semaphore(2)) { private var inside = 0 suspend fun visit() { lane.acquire() try { inside++ println(inside) } finally { inside-- lane.release() } } }

Семафор на 2 разрешения. Четыре корутины печатают метку входа, ждут 30 мс и печатают выход, каждый раз забирая и возвращая разрешение в finally.

Класс Booth с семафором на два места и методом serve. Три запуска по очереди вызывают обслуживание и выводят строку "ok" внутри участка.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить