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

Что такое горячий поток?

2.2 Middle🔥 161 комментариев
#Kotlin основы#Многопоточность и асинхронность

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

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

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

Что такое горячий поток (Hot Flow) в Kotlin Flow?

Горячий поток (Hot Flow) в контексте Kotlin Coroutines и Flow — это поток данных, который начинает излучать (emit) элементы независимо от наличия активных коллекторов (collectors). Его "горячая" природя означает, что источник данных активен постоянно, и события происходят в реальном времени, даже если никто их не наблюдает. Это противоположность холодному потоку (Cold Flow), который начинает генерацию данных только при начале коллекции и для каждого коллектора создаёт отдельную последовательность.

Ключевые характеристики горячего потока:

  • Независимая активность: Источник данных (например, событие от UI, обновление состояния) производит элементы самостоятельно.
  • Поток данных в реальном времени: Элементы могут быть потеряны, если в момент их излучения нет активного коллектора.
  • Общий источник для всех коллекторов: Все коллекторы подключаются к одному и тому же живому потоку данных и получают одинаковые элементы, излученные после их подключения.
  • Часто используется для событий и состояний: Идеально подходит для моделирования непрерывных событий (клики пользователя, обновления сети) или изменяемого состояния (например, текущее значение в StateFlow).

Примеры горячих потоков в Kotlin:

В библиотеке Kotlin Coroutines основными реализациями горячего потока являются StateFlow и SharedFlow.

1. StateFlow

StateFlow представляет собой поток с состоянием, который хранит текущее значение и излучает его новым коллекторам сразу при подключении, а затем излучает каждое обновление этого состояния.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

// Создание горячего StateFlow
val stateFlow = MutableStateFlow(0) // начальное состояние = 0

fun main() = runBlocking {
    // Излучаем новое состояние НЕЗАВИСИМО от коллекторов
    stateFlow.value = 1
    stateFlow.value = 2

    // Коллектор 1 начинает коллекцию ПОСЛЕ некоторых изменений
    launch {
        stateFlow.collect { value ->
            println("Collector 1 received: $value")
        }
    }

    delay(10)
    // Коллектор получит текущее состояние (2) и затем новые обновления
    stateFlow.value = 3 // Все активные коллекторы получат 3

    // Коллектор 2 подключается позже и сразу получает текущее состояние (3)
    launch {
        stateFlow.collect { value ->
            println("Collector 2 received: $value")
        }
    }

    delay(10)
    stateFlow.value = 4 // Оба коллектора получат 4
}

2. SharedFlow

SharedFlow предназначен для событий, которые не имеют "текущего значения". Он излучает события всем активным коллекторам, но не хранит состояние. Можно настроить повтор (replay) прошлых событий для новых коллекторов.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

// Создание горячего SharedFlow с replay = 2 (новые коллекторы получат 2 последних события)
val sharedFlow = MutableSharedFlow<Int>(replay = 2)

fun main() = runBlocking {
    // Излучаем события
    sharedFlow.emit(1)
    sharedFlow.emit(2)
    sharedFlow.emit(3)

    // Коллектор подключится и получит replay-данные (2 и 3), затем новые события
    launch {
        sharedFlow.collect { value ->
            println("Collector received: $value")
        }
    }

    delay(10)
    sharedFlow.emit(4) // Коллектор получит 4
}

Сравнение с холодным потоком (Cold Flow):

Чтобы понять разницу, рассмотрим базовый холодный поток:

// Cold Flow: flow { ... }
val coldFlow = flow {
    println("Cold Flow started emitting")
    emit(1)
    emit(2)
    emit(3)
}

fun main() = runBlocking {
    // Каждая коллекция запускает независимую последовательность
    coldFlow.collect { println("Collector A: $it") }
    // При новой коллекции поток снова выполняется полностью
    coldFlow.collect { println("Collector B: $it") }
}

Когда использовать горячий поток?

  • Общее состояние приложения: Например, StateFlow для ViewModel в Android для предоставления UI состояния.
  • События в реальном времени: Клики, сообщения от сервера через WebSocket, уведомления.
  • Когда данные независимы от потребителя: Источник данных существует сам по себе (например, таймер, системные события).

Важное предостережение: поскольку элементы могут быть излучены без активного коллектора, в чистом SharedFlow без replay есть риск "потерять" события. Поэтому выбор между StateFlow (для состояния) и SharedFlow (для событий с возможностью replay) должен быть осознанным, исходя из требований к данным.

Что такое горячий поток? | PrepBro