| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- 디자인패턴
- Design Pattern
- 추상 팩토리
- Functional Programming
- 코틀린멀티플랫폼
- 프로토타입 패턴
- kmp
- android designsystem
- define
- designPattern
- builderPattern
- 디자인패턴 #
- 코틀린
- 옵저버 패턴
- Observer Pattern
- ㅋㅁ
- 팩토리 메소드
- compose
- 추상팩토리패턴
- PrototypePattern
- kotlin multiplatform
- Kotlin
- material3
- factory method
- 코루틴
- 안드로이드 디자인시스템
- Abstract Factory
- 빌터패턴
- 함수형프로그래밍
- Coroutines
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
12장 디스패처2 본문
프로젝트 룸의 가상 스레드 사용하기
jvm플랫폼은 프로젝트 룸이라는 새로운 기술을 발표함 -> 일반적인 스레드보다 훨씬 가벼운 가상 스레드를 도입.
코틀린 코루틴은 취소를 쉽게하고, 테스트에서 가상시간을 사용하는 등 훨씬 놀라운 기능을 갖추고 있다.
프로젝트 룸이 정말로 유용한 경우는 스레드를 블로킹할 수밖에 없는 Dispatcher.IO 대신 가상 스레드를 사용할때!
jvm19 이상이며, --enable -preview 플래그를 사용해 정식 출시전 기능을 허용해야됨.
val LoomDispatcher = Executors
.newVirtualThreadPerTaskExecutor()
.asCoroutineDispatcher()
object LoomDispatcher: ExecutorCoroutineDispatcher() {
override val executor: Executor = Executor { command ->
Thread.startVirtualThread(command)
}
override fun close() {
error("Cannot be invoked on Dispatcher.LOOM")
}
override fun dispatch(context: CoroutineContext, block: Runnable) {
executor.execute(block)
}
}
val Dispatcher.Loom = LoomDispatcher()
다른 디스패쳐보다 메모리 사용도 적고, 프로세스 처리 시간도 적다.
*아직은 시작단계라 실제로 사용은 어렵지만, 기억은 해두자
제한받지 않는 디스패처
Dispatchers.Unconfined
스레드를 바꾸지 않는다는 점에서 이전 디스패처들과 다릅니다.
디스패처가 시작되면 시작한 스레드에서 실행되고, 재개되면, 재개한 스레드에서 실행이 됩니다.
suspend fun main(): Unit = withContext(newSingleThreadContext("Thread1")) {
var continuation: Continuation<Unit>? = null
launch(newSingleThreadContext("Thread2")) {
delay(1000)
continuation?.resume(Unit)
}
launch(Dispatchers.Unconfined) {
println(Thread.currentThread().name)
suspendCancellableCoroutine<Unit> {
continuation = it
}
println(Thread.currentThread().name)
delay(1000)
println(Thread.currentThread().name)
}
}
//Thread1
//Thread2
//kotlinx.coroutines.DefaultExecutor
단위 테스트 할때 유용하게 사용된다.
모든 스코프에서 Dispatchers.Unconfined를 사용하면 모든 작업이 같은 스레드에서 실행되기 때문에 연산의 순서를 훨씬 쉡게 통제 가능하다. 하지만, runTes를 사용하자.....
현업에서 상용코드에는 사용하지 않는 디스패처...
메인 디스패처로 즉시 옮기기
withContext가 호출이 되면 코루틴은 중단되고 큐에서 기다리다 재개된다.
스레드에서 이미 실행되고 있는 코루틴을 다시 배정하려면, 불필요한 비용이 들어가게 된다.
suspend fun showUser(user: User) =
withContext(Dispatchers.Main) {
userNameElement.text = user.name
...
}
위 함수가 이미 메인 디스패처에서 시작되었다면, 다시 실행할 스레드를 메인으로 배정하는 쓸데없는 비용이 발생한다.
Dispatcher.Main.immediate를 사용하여 메인 스레드에서 호출하면 배정없이 즉시 실행된다.
suspend fun showUser(user: User) =
withContext(Dispatchers.Main.immediate) {
userNameElement.text = user.name
...
}
*즉시배정은 메인 스레드만 가능하다
컨티뉴에이션 인터셉터
디스패칭은 코틀린 언어에서 지원하는 ContinuationInterceptor기반으로 작동한다.
ContinuationInterceptor라는 코루틴 컨텍스트는 코루틴이 중단되었을때,
interceptContiunation 메소드를 이용해 컨티뉴에이션 객체를 수정 및 랩핑한다.
releaseInterceptedContiunation 메소드 컨티뉴에이션이 종료되었을 때 호출된다.
public interface ContinuationInterceptor : CoroutineContext.Element {
public companion object Key : CoroutineContext.Key<ContinuationInterceptor>
public fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T>
public fun releaseInterceptedContinuation(continuation: Continuation<*>) {
/* do nothing by default */
}
//...
}
디스패처는 특정 스레드 풀에서 실행되는 DispatchedContinuation으로 컨티뉴에이션 객체를 랩핑하기 위해서 interceptContiunation 메소드를 사용한다. DispatchedContinuation은 디스패처가 작동하는 핵심요소이다.
*runTest 와 같은 테스트 라이브러리에서 동일한 컨텍스트를 사용하고 있다. 컨텍스트의 각 원소는 고유한 키를 가진다.
=> 일부 단위 테스트에서는 디스패처를 주입해 기존 디스패처를 테스트 디스패처로 대체한다.
작업의 종류에 따른 각 디스패처의 성능 비교
독립된 작업을 하는 100개의 코루틴을 실행
순서대로 1초 중단, 1초 스레드 블로킹, CPU 또는 메모리 집약적 작업 수행
*평균 실행 시간
| 중단 | 블로킹 | CPU 집약연산 | 메모리 집약연산 | |
| 싱글 스레드 | 1,002 | 100,003 | 39,103 | 94,358 |
| Default Dispatcher | 1,002 | 13,003 | 8,473 | 21,416 |
| IO Dispatcher | 1,002 | 2,003 | 9,893 | 20,776 |
| 스레드 100개 | 1,002 | 1,003 | 16,379 | 21,004 |
1. 코루틴의 중단은 사용하는 스레드가 얼마나 많은지는 문제가 되지 않음.
2. 스레트블로킹이 존재할 경우, 스레드가 수가 많을수록 코루틴의 종료시간이 빨라짐.
3. CPU 집약적 연산에서는 Default 가 가장 좋은 선택.
4. 메모리 집약적 연산일 경우 더 많은 스레드를 사용하는 것이 좀 더 나음.
'Coroutine > 코틀린 코루틴' 카테고리의 다른 글
| 12장 디스패처1 (0) | 2026.03.03 |
|---|---|
| 11장 코루틴 스코프 함수 - 2 (0) | 2026.02.21 |
| 11장 코루틴 스코프 함수 - 1 (1) | 2026.02.18 |
| 10장 예외처리 (0) | 2026.02.09 |
| 9장 취소 (0) | 2026.02.01 |
