Комментарии 9
Да ёлки палки, есть semaphore, а на его бинарной вариации можно собрать что угодно синхронизированное из мира coroutines. Один раз попробовать и альтернативы и не нужны будут, мне так старший товарищ дал пинка под одно место (спасибо ему огромное) и я написал реализацию reentrantlock (стандартную никак не завезут), но для coroutines.
P.s. кстати непонятно почему именно их вы не упомянули.
Да, это правда, семафоры как и мьютексы даже есть в библиотеке kotlinx.coroutines и на их основе можно конструировать что угодно. Про них тоже собирался написать, но решил что статья получается слишком большая и разбил ее на две части. Первая часть получилась попроще, про более известные методы синхронизации и StateFlow.
А вот как раз во второй части будут семафоры с большим количеством примеров, SharedFlow, расскажу про практику выполнения кода на выделенном потоке и думаю даже удастся рассказать про каналы и акторы)
Мьютекс и семафор в принципе единственное что там есть. Все остальные примитивы синхронизации используют пакеты jvm и в мультиплатформе не применимо из-за этого. Варианты flow и каналов не рассматриваем, они хоть и потокобезопасны, но вот как на них сделать потокобезопасную коллекцию я не представляю. Да и вообще синхронизировать доступ к произвольной переменной.
"В отличие от CyclicBarrier в конструкторе мы задаем"... Тут опечатка, вместо CyclicBarrier нужно CountDownLatch. Спасибо за статью!
У StateFlow
есть потокобезопасный метод update
. Это я к тому, что нет необходимости синхронизации в вашей реализации CountdownBarrier
а зачем помечать counterValue
и countLeftToReleaseBarrier
как Synchronized
?
В случае с countLeftToReleaseBarrier переменная stateFlow сама помечена как var и может измениться внутри другой функции помеченной Synchronized. То есть может измениться не только value а сам stateFlow.
А в случае с counterValue может быть дополнительная синхронизация действительно излишняя, ведь поле value синхронизировано само по себе. Как писали в предыдущем комментарии CountDownBarrier можно было бы избавить от Synchronized целиком с помощью функции update, но я решил в коде оставить авторское решение и не править ничего, так наверное честнее)
От потоков к корутинам: как и почему видоизменились примитивы синхронизации в языке Kotlin (Часть 1)