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

Предел задач в Kotlin

Когда внутри участка есть delay или долгий расчет, иногда важно не пускать туда все задачи сразу. Семафор с малым числом разрешений превращается в шлюз по параллелизму.

При двух разрешениях одновременно работают не больше двух корутин, остальные стоят в очереди на acquire, пока кто-то не закончит участок и не вернет слот:

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 cap = Semaphore(2) val jobs = List(5) { id -> launch { cap.acquire() try { println("work $id") delay(100) } finally { cap.release() } } } joinAll(*jobs.toTypedArray()) } }

По меткам "work" в консоли видно волну: сначала пара id, затем следующая пара, пока все пять не пройдут. Без семафора все пять строк появились бы сразу.

Тот же шлюз оборачивают в функцию, чтобы не дублировать try в каждом запуске. Общий семафор живет снаружи, а тяжелый шаг лежит в лямбде:

import kotlinx.coroutines.delay import kotlinx.coroutines.sync.Semaphore class Loader(private val cap: Semaphore = Semaphore(2)) { suspend fun runBatch(label: String) { cap.acquire() try { println(label) delay(80) } finally { cap.release() } } }

Шлюз на два одновременных доступа. Шесть корутин печатают букву этапа, ждут 60 мс и завершаются. Убедитесь по логу, что активных этапов не больше двух.

Класс Ripener с семафором на 2 и методом, где пауза 120 мс. Пять фоновых запусков готовят разные метки "a" … "e" и ждут общего конца.

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