티스토리 뷰
728x90
1. Stream과 Flow의 차이점
1.1 동기 vs 비동기
Stream
: 자바의Stream
API는 동기적으로 작동합니다. 이는 한 번에 하나의 스레드에서만 데이터를 처리할 수 있으며, 비동기 처리에는 적합하지 않습니다.Flow
: 비동기적으로 데이터를 처리할 수 있도록 설계된 코틀린의 API입니다. 플로우는 코루틴을 기반으로 하며, 동시에 여러 작업을 처리할 수 있습니다. 지연된 데이터를 처리하거나 리액티브 프로그래밍이 필요할 때 유리합니다.
1.2 백프레셔(Backpressure) 지원
Stream
: 자바의 스트림은 백프레셔를 지원하지 않습니다. 백프레셔는 데이터가 너무 빨리 방출되어 소비자가 이를 감당할 수 없는 상황을 처리하는 메커니즘인데, 스트림은 데이터 소비 속도를 제어할 방법이 없습니다.Flow
: 백프레셔를 자연스럽게 처리할 수 있습니다. 이는 플로우가 리액티브 프로그래밍에 맞게 설계되어 있으며, 소비자가 데이터를 처리할 수 있을 때만 데이터를 전달합니다.
1.3 콜드 스트림 vs 핫 스트림
Stream
: 자바의 스트림은 콜드 스트림입니다. 이는 데이터를 요청할 때만 계산을 시작하는 방식을 의미하며, 요청이 있을 때마다 항상 새로 계산됩니다.Flow
:Flow
도 기본적으로 콜드 스트림입니다. 데이터를 요청하는 시점에 데이터 흐름이 시작되며, 이전에 방출된 데이터는 다시 수신되지 않습니다.
1.4 차가운(Cold) vs 뜨거운(Hot) 스트림의 지원
Stream
: 자바의 스트림은 항상 차가운 스트림(Cold Stream)만을 지원합니다. 이는 데이터를 요청할 때마다 새로 데이터를 제공한다는 의미입니다.Flow
: 플로우는 기본적으로 차가운 스트림을 제공하지만,SharedFlow
나StateFlow
를 통해 뜨거운 스트림(Hot Stream)도 지원합니다. 뜨거운 스트림은 이미 방출된 데이터를 여러 소비자가 수신할 수 있는 방식입니다. 이를 통해 실시간 이벤트 스트림과 같은 동작을 지원합니다.
1.5 멀티스레드 지원
Stream
: 자바의Stream
은 멀티스레드 환경에서 기본적으로 사용할 수 없으며, 병렬 스트림(parallelStream
)을 사용해야만 멀티스레드 처리가 가능합니다.Flow
: 플로우는 멀티스레드 환경에서 자연스럽게 작동하며, 별도의 설정 없이도 비동기 작업을 병렬로 처리할 수 있습니다. 코루틴을 활용하여 여러 스레드에서 효율적으로 동작합니다.
2. Stream과 Flow 사용 시점
언제 Stream
을 사용해야 할까?
- 동기적 데이터 처리가 필요한 경우:
- 단일 스레드에서 순차적으로 데이터를 처리할 때는
Stream
이 적합합니다. 자바의 스트림은 동기적 작업 처리에 뛰어나며, 큰 데이터 집합을 필터링, 변환, 집계할 때 유용합니다. - 예를 들어, 컬렉션에서 데이터를 필터링하고 동기적으로 처리할 때
Stream
을 사용하는 것이 좋습니다.
- 단일 스레드에서 순차적으로 데이터를 처리할 때는
- 단순한 동기 작업:
- 비동기 처리가 필요하지 않은, 단일 스레드에서 순차적 데이터 처리만 필요한 상황에서
Stream
을 사용하는 것이 적합합니다.
- 비동기 처리가 필요하지 않은, 단일 스레드에서 순차적 데이터 처리만 필요한 상황에서
언제 Flow
를 사용해야 할까?
- 비동기 데이터 처리가 필요한 경우:
- 네트워크 요청, 파일 입출력, 센서 데이터 수집 등 비동기 작업을 처리할 때
Flow
를 사용하면 좋습니다. 코루틴을 기반으로 하여 비동기 작업을 효율적으로 처리하고, 비동기 스트림을 자연스럽게 구현할 수 있습니다.
- 네트워크 요청, 파일 입출력, 센서 데이터 수집 등 비동기 작업을 처리할 때
- 리액티브 프로그래밍:
- 플로우는 리액티브 프로그래밍을 지원하므로, 백프레셔가 필요하거나, 실시간 데이터 스트림(주식 가격, 센서 데이터 등)을 처리하는 경우에 유리합니다.
- 멀티스레드 환경:
- 멀티스레드 환경에서 여러 비동기 작업을 동시에 처리해야 하는 경우,
Flow
가 자연스럽게 작동하며 코루틴을 기반으로 안전하게 동작합니다.
- 멀티스레드 환경에서 여러 비동기 작업을 동시에 처리해야 하는 경우,
- 백프레셔가 필요한 경우:
- 데이터 생산 속도가 빠르고, 소비자가 그 데이터를 따라잡기 어려운 상황에서 백프레셔 처리를 위해
Flow
를 사용하는 것이 적합합니다.
- 데이터 생산 속도가 빠르고, 소비자가 그 데이터를 따라잡기 어려운 상황에서 백프레셔 처리를 위해
예시: Stream
사용 (동기적 데이터 처리)
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
Stream.of(1, 2, 3, 4, 5)
.filter(num -> num % 2 == 0)
.map(num -> num * 2)
.forEach(System.out::println);
}
}
예시: Flow
사용 (비동기 데이터 처리)
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
(1..5).asFlow()
.filter { it % 2 == 0 }
.map { it * 2 }
.collect { println(it) }
}
3. Flow를 사용해야 하는 이유
- 비동기 작업에 최적화: 네트워크 요청, 파일 입출력 등 비동기 작업을 효율적으로 처리할 수 있습니다.
- 리액티브 프로그래밍:
Flow
는 리액티브 프로그래밍 패러다임을 지원하며, 데이터 생산자와 소비자 간의 속도 차이를 처리할 수 있는 백프레셔 기능을 제공합니다. - 멀티스레드 작업: 비동기적 멀티스레드 환경에서 안전하게 작업을 병렬 처리할 수 있습니다.
- 플로우의 연산자:
map
,filter
,transform
등의 연산자를 활용하여 데이터 스트림을 유연하게 변환하고, 백프레셔와 에러 처리를 지원합니다.
요약
Stream
은 동기적 데이터 처리에 적합하며, 주로 순차적 작업이 필요한 상황에서 사용됩니다.Flow
는 비동기적 데이터 처리와 리액티브 프로그래밍을 지원하며, 특히 네트워크 요청이나 백프레셔가 필요한 작업에 적합합니다.- 멀티스레드 환경에서 비동기 작업을 효율적으로 처리하려면
Flow
를 사용하는 것이 더 유리합니다.
간단하게, 일반적인 동기적 프로그래밍 작업에서는 **Stream을 사용하고, 비동기적 작업을 처리할 때는 코루틴 기반의 Flow를 사용한다고 생각하면 됩니다.**
728x90
'개발 언어 > 코틀린' 카테고리의 다른 글
kotlin - coroutine (부록4) Flow (1) | 2024.09.05 |
---|---|
kotlin - coroutine (부록2) Channel과 Flow의 사용 예시 (0) | 2024.09.05 |
kotlin - coroutine (부록1) launch VS coroutineScope (0) | 2024.09.05 |
kotlin - coroutine (7) 실제 프로젝트 적용 예제 (2) | 2024.09.05 |
kotlin - coroutine (6) 코루틴 취소 및 타임아웃 (0) | 2024.09.05 |
댓글