Нужна ли синхронизация корутин, если одни работают в IO Thread, а другие в главном потоке, и все инкрементируют общую переменную

«Нужна ли синхронизация корутин, если одни работают в IO Thread, а другие в главном потоке, и все инкрементируют общую переменную» — вопрос из категории Coroutines и Flow, который задают на 23% собеседований Android Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, синхронизация необходима, так как инкремент (count++) не является атомарной операцией. Даже если корутины работают в разных потоках (IO и Main), может возникнуть состояние гонки.

Пример с Mutex:

val mutex = Mutex()
var count = 0

fun increment() = runBlocking {
    repeat(100) {
        launch(Dispatchers.IO) {
            mutex.withLock {
                count++
            }
        }
    }
}

Альтернативы:

  • AtomicInteger для простых случаев
  • synchronized блоки (но менее идиоматично для корутин)
  • @Volatile не поможет, так как не делает операцию атомарной