Как стать автором
Обновить

От потоков к корутинам: как и почему видоизменились примитивы синхронизации в языке Kotlin (Часть 1)

Уровень сложностиСредний
Время на прочтение18 мин
Количество просмотров14K
Всего голосов 13: ↑13 и ↓0+13
Комментарии9

Комментарии 9

Да ёлки палки, есть semaphore, а на его бинарной вариации можно собрать что угодно синхронизированное из мира coroutines. Один раз попробовать и альтернативы и не нужны будут, мне так старший товарищ дал пинка под одно место (спасибо ему огромное) и я написал реализацию reentrantlock (стандартную никак не завезут), но для coroutines.

P.s. кстати непонятно почему именно их вы не упомянули.

Да, это правда, семафоры как и мьютексы даже есть в библиотеке kotlinx.coroutines и на их основе можно конструировать что угодно. Про них тоже собирался написать, но решил что статья получается слишком большая и разбил ее на две части. Первая часть получилась попроще, про более известные методы синхронизации и StateFlow.

А вот как раз во второй части будут семафоры с большим количеством примеров, SharedFlow, расскажу про практику выполнения кода на выделенном потоке и думаю даже удастся рассказать про каналы и акторы)

Мьютекс и семафор в принципе единственное что там есть. Все остальные примитивы синхронизации используют пакеты jvm и в мультиплатформе не применимо из-за этого. Варианты flow и каналов не рассматриваем, они хоть и потокобезопасны, но вот как на них сделать потокобезопасную коллекцию я не представляю. Да и вообще синхронизировать доступ к произвольной переменной.

"В отличие от CyclicBarrier в конструкторе мы задаем"... Тут опечатка, вместо CyclicBarrier нужно CountDownLatch. Спасибо за статью!

Спасибо за отзыв, но там написано правильно. Имелось ввиду в классе CyclicBarrier мы задаем число Java потоков, а в нашей реализации CoroutinesBarrier мы задаем именно число корутин, при которых барьер освобождается. Сейчас поправлю эту фразу в статье, чтобы было понятнее.

У StateFlow есть потокобезопасный метод update. Это я к тому, что нет необходимости синхронизации в вашей реализации CountdownBarrier

Спасибо, не знал про эти методы, действительно получилось бы еще лаконичнее и без блоков @Synchronized. В списке преимуществ StateFlow добавлю про потокобезопасные методы compareAndSet, update, updateAndGet, getAndUpdate.

а зачем помечать counterValue и countLeftToReleaseBarrier как Synchronized?

В случае с countLeftToReleaseBarrier переменная stateFlow сама помечена как var и может измениться внутри другой функции помеченной Synchronized. То есть может измениться не только value а сам stateFlow.

А в случае с counterValue может быть дополнительная синхронизация действительно излишняя, ведь поле value синхронизировано само по себе. Как писали в предыдущем комментарии CountDownBarrier можно было бы избавить от Synchronized целиком с помощью функции update, но я решил в коде оставить авторское решение и не править ничего, так наверное честнее)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий