← Назад к вопросам

Защищают ли Coroutines от race condition

1.0 Junior🔥 111 комментариев
#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Защищают ли корутины от race condition?

Краткий ответ: Нет, корутины сами по себе НЕ защищают от race condition (состояния гонки). Они предоставляют инструменты для более удобного написания асинхронного и параллельного кода, но проблема конкурентного доступа к общему изменяемому состоянию остается актуальной.


Почему race condition возникает в корутинах

Состояние гонки — это ошибка, возникающая, когда несколько потоков или корутин одновременно обращаются к общим изменяемым данным, и хотя бы одна операция является записью. Результат выполнения становится зависимым от неуправляемого порядка выполнения.

Корутины в Kotlin могут выполняться в одном потоке (например, Dispatchers.Main) или в нескольких (Dispatchers.Default, Dispatchers.IO). Если корутины запущены в многопоточном диспетчере, они выполняются параллельно в разных потоках, создавая классические условия для race condition.

Пример опасного кода

import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis

fun main() = runBlocking {
    var counter = 0 // Разделяемое изменяемое состояние
    val n = 1000 // Количество корутин
    
    val time = measureTimeMillis {
        coroutineScope {
            repeat(n) {
                launch(Dispatchers.Default) { // Запускаем в пуле потоков
                    counter++ // Неатомарная операция: READ -> INCREMENT -> WRITE
                }
            }
        }
    }
    
    println("Счетчик = $counter за ${time}ms")
    // Частый результат: "Счетчик = 998 за 15ms", а не 1000
}

Операция counter++ не является атомарной. Она состоит из чтения значения, увеличения и записи. Две корутины могут прочитать одно и то же значение, увеличить его и записать, что приводит к потере одного из инкрементов.


Инструменты для защиты от race condition в корутинах

Kotlin предоставляет несколько механизмов для безопасного управления общим состоянием:

1. Атомарные типы (Atomic)

Классы из пакета java.util.concurrent.atomic, такие как AtomicInteger, обеспечивают атомарные операции.

import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicInteger

fun main() = runBlocking {
    val counter = AtomicInteger(0)
    
    coroutineScope {
        repeat(1000) {
            launch(Dispatchers.Default) {
                counter.incrementAndGet() // Атомарная операция
            }
        }
    }
    
    println("Счетчик = ${counter.get()}") // Всегда 1000
}

2. Мьютексы (Mutex)

Mutex из kotlinx.coroutines.sync предоставляет механизм взаимного исключения специально для корутин. Он не блокирует поток, а приостанавливает корутину.

import kotlinx.coroutines.*
import kot
Защищают ли Coroutines от race condition | PrepBro