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

Замок в Kotlin

У Mutex есть пара методов lock и unlock. Первый приостанавливает корутину, пока замок занят, второй отдает его следующему ожидающему. Между ними лежит критический участок.

Если исключение вылетит внутри участка, замок всё равно нужно снять. Парой try и finally unlock вызывают даже при ошибке:

import kotlinx.coroutines.sync.Mutex suspend fun addTicket(gate: Mutex, counter: IntArray) { gate.lock() try { counter[0]++ } finally { gate.unlock() } }

На практике счетчик хранят снаружи, а под замком меняют его поле. Две корутины крутят приращение билетов и после joinAll сверяют сумму:

import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex fun main() { runBlocking { var tickets = 0 val gate = Mutex() val jobs = List(2) { launch { repeat(500) { gate.lock() try { tickets++ } finally { gate.unlock() } } } } joinAll(*jobs.toTypedArray()) println(tickets) } }

Тот же каркас подходит, когда между приращениями есть пауза: замок удерживается только на время изменения, а delay выполняется уже снаружи:

import kotlinx.coroutines.delay import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex suspend fun bump(gate: Mutex, slot: IntArray) { delay(10) gate.lock() try { slot[0]++ } finally { gate.unlock() } } fun main() { runBlocking { val gate = Mutex() val slot = intArrayOf(0) val jobs = listOf( launch { bump(gate, slot) }, launch { bump(gate, slot) }, ) joinAll(*jobs.toTypedArray()) println(slot[0]) } }

Общий Mutex и переменная coins типа Int. Две фоновые корутины по 300 раз увеличивают монеты под ручным замком с finally. После ожидания обеих выведите итог.

Счетчик visits и один замок. Три корутины делают короткую паузу, затем под замком добавляют единицу. Дождитесь всех и напечатайте число визитов.

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