훌륭한 개발자가 되기 위하여
스레드 기반 작업의 한계, Coroutine Dispatcher 본문
스레드 기반 작업의 한계
- 스레드 기반 작업들은 작업의 전환이 어렵고, 전환에 드는 비용이 비싸다.
- 간단한 작업에서는 콜백 방식 or 체이닝 함수를 사용하여 스레드 블로킹 문제를 해결할 수 있지만 실제 애플리케이션은 작업 간의 종속성이 복잡해 스레드 블로킹이 발생하는 것은 필연적이다.
코루틴을 사용하면 스레드의 사용 권한을 양보 할 수 있다.
runBlocking : 이 함수를 호출한 스레드를 사용해 실행되는 코루틴을 만들어낸다.
→ runBlocking 코루틴이 종료될 때 스레드 점유가 해제된다.
runBlocking 함수는 시작구에서만 사용하고 내부에서 coroutine을 추가로 생성할 때는 launch 함수를 사용해야 한다.
Coroutine Dispatcher
코루틴을 스레드로 보내 실행시키는 객체
새로운 코루틴이 Dispatcher 안에 작업 대기열에 적재되고 쉬고 있는 스레드가 있으면 그 스레드로 보내져 실행된다.
단일 스레드 디스패처 : 하나의 스레드를 가지는 디스패처
val singleThreadDispatcher: CoroutineDispatcher =
newSingleThreadContext("SingleThread")
Dispatcher 넘겨줄 때는 launch 함수에 context 인수에 디스패처를 넘겨주면 됨
fun main() = runBlocking<Unit> {
launch(singleThreadDispatcher) {
println("[${Thraed.currentThread().name}] 실행")
}
}
멀티 스레드 디스패처 만드는 법
val multiThreadDispatcher: CoroutineDispatcher = newFixedThreadPoolContext(2, “MultiThread)
위 방법은 deprecated이므로 코루틴 라이브러리에서 제공하는 디스패처를 사용하자
미리 정의된 CoroutineDispatcher
1. Dispatchers.IO
- 네트워크 요청이나 DB 입출력 작업을 실행하는 디스패처
- 사용할 수 있는 스레드의 수 : 64와 JVM에서 사용할 수 있는 프로세서의 수 중 큰 값
- 싱글톤 객체라 launch 인자로 넘겨 사용
- limitedParallelism 함수를 사용하면 공유 스레드 풀의 별도 스레드를 사용하는 디스패처를 만들 수 있다. → 다른 작업에 방해 받지 않아야 하는 중요 작업
fun main() = runBlocking<Unit> {
launch(Dispatchers.IO) {
launch {
println("[${Thread.currentThread().name}] 작업 1 실행")
}
launch {
println("[${Thread.currentThread().name}] 작업 2 실행")
}
launch {
println("[${Thread.currentThread().name}] 작업 3 실행")
}
}
}
2. Dispatchers.Default
- CPU 바운드 작업을 위한 디스패처
- CPU 바운드 작업 : 이미지, 동영상 처리나 대용량 데이터 변환 같이 끊이지 않고 연산이 필요한 작업
→ 머신에서 사용할 수 있는 프로세스의 수와 2 중 큰 값
디스패처가 다른데 Thread 이름이 같은 이유 : 코루틴 라이브러리의 공유 스레드풀 때문 → 코루틴 라이브러리는 스레드의 생성과 관리를 효율적으로 할 수 있도록 애플리케이션 레벨의 공유 스레드 풀을 제공한다.
Limited Parallelism() : 특정 작업을 위해 사용할 수 있는 Thread 개수를 제한함 → Dispatchers.Default의 스레드 중 일부만을 사용하는 디스패처를 만들 수 있다.
Dispatchers.Defaults는 Default 스레드 내부에서 개수를 제한해서 사용하지만
Dispatchers.IO와 Dispatchers.Default는 코루틴 라이브러리의 공유 스레드 풀을 사용한다.
3. Dispatchers.Main
- 메인 스레드에서의 작업을 위한 디스패처
- Dispatchers.Main은 어느 스레드에서 코루틴을 실행 요청하든 작업 대기열에 먼저 적재한 후 Main Thread가 비었을 때 코루틴을 보냄
- Dispatchers.Main.immediate는 코루틴을 실행하는 코드가 메인 스레드에서 실행되고 있다면, 작업 대기열에 적재 없이 그대로 메인 스레드에서 실행될 수 있게 함 → 코루틴이 백그라운드 스레드에서 실행될 경우 Dispatcher.Main과 같이 적재 후 메인 스레드로 보냄
'안드로이드' 카테고리의 다른 글
코루틴으로부터 결과 수신 받기 (0) | 2025.01.08 |
---|---|
코루틴 제어 (0) | 2025.01.07 |
[Android] Ktlint적용하기 (0) | 2024.10.29 |
[Android | Kotlin] 안드로이드 기본 앱과 연동하기 (1) | 2024.01.03 |
[Android | Kotlin] 콘텐츠 프로바이더 이해하기 (0) | 2024.01.03 |