우테코 8기/Kotlin

Flow, StateFlow, SharedFlow

Reddish 2026. 10. 4. 00:19
반응형

Stream


시간의 흐름에 따라 여러 값이 전달되는 데이터의 흐름이다.

  • 함수가 값 하나를 반환하는 것과 달리, 여러 값을 순차적으로 전달한다
  • ex. 검색어 입력, 위치 변경, 서버 응답

Hot Stream vs Cold Stream


  • Cold Stream
    • 구독자가 수집을 시작할 때 각자 새로운 생산 작업이 시작됨
    • 구독자가 독립적으로 스트림이 실행됨
    • 일반적인 flow {} 가 대표적이다
val numbers = flow {
    println("Flow 시작")
    emit(1)
    emit(2)
}

numbers.collect { println("A: $it") }
numbers.collect { println("B: $it") }

// "Flow 시작"이 두 번 출력된다. 각 collect가 별도의 실행을 시작해서이다.
  • Hot Stream
    • 구독 여부와 별개로 하나의 생산 흐름이 존재한다
    • 여러 구독자가 하나의 스트림을 공유한다
    • StateFlow, SharedFlow가 대표적이다.
val events = MutableSharedFlow<Int>()

launch {
    events.collect { println("A: $it") }
}
launch {
    events.collect { println("B: $it") }
}

events.emit(1)

A와 B가 같은 값을 전달받는다.

Cold Stream과 Hot Stream의 차이는 3가지이다.

  1. 데이터가 생성되는 위치
  2. 생산자가 발행한 데이터를 동시에 여러 소비자들이 수신할 수 있는지 여부
  3. 스트림이 데이터를 생산하는 시점
구분 Cold Stream Hot Stream
생산 시작 구독할 때 생산자의 동작에 따라
실행 공유 구독자마다 독립 실행 여러 구독자가 공유
구독 전 데이터 아직 생산되지 않음 놓칠 수 있음
대표 예시 Flow, HTTP 요청 StateFlow, SharedFlow

Hot의 의미는 "구독자와 무관하게 값(상태)이 살아있다"는 것이지, collect를 안 해도 값이 자동으로 흘러간다는 뜻이 아니다. 구독자에게 값을 전달하려면 여전히 collect가 필요하다.

Flow


Flow는 코루틴 기반 비동기 데이터 스트림이다. (기본적으로는 ColdFlow이다)

StateFlow, SharedFlow


  • StateFlow: 구독자가 없어도 현재 상태를 유지하는 Hot Stream
    • 항상 초기값과 최신 값이 존재한다.
    • 새로운 구독자는 최신 값을 즉시 받는다.
    • 같은 값을 연속으로 넣으면 다시 방출하지 않는다.
    • ex. 로딩 상태, 사용자 정보, 화면의 UiState
  • SharedFlow: 값을 여러 구독자에게 공유하는 Hot Stream
    • 여러 구독자에게 값을 전달하는 Hot Flow
    • 초기값이 필수는 아니다.
    • replay 로 새 구독자에게 이전 값을 몇 개 전달할지 결정한다.
    • ex. 이벤트나 여러 구독자에게 공유할 데이터

 

구분 StateFlow SharedFlow
목적 현재 상태 보관 값/이벤트 공유
초기값 존재 O X
최신 값 접근 value 직접 접근 불가
새 구독자 최신 상태를 즉시 받음 replay 설정에 따라 받음
중복 값 연속 중복 방출 억제 기본적으로 방출
대표 사용처 화면 상태 알림, 이벤트 스트림
반응형

'우테코 8기 > Kotlin' 카테고리의 다른 글

Kotlin Annotation Retention  (0) 2026.09.20
Kotlin coroutine - suspend 함수  (0) 2026.09.05
expect / actual 키워드 (Kotlin Multiplatform, KMP)  (0) 2026.08.17
가변성을 제한하라  (0) 2026.07.19
Annotation과 Annotation Target  (2) 2026.06.03