일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- minikube
- 정보처리기사 실기
- CKA 기출문제
- PETERICA
- IntelliJ
- 오블완
- kotlin querydsl
- 기록으로 실력을 쌓자
- kotlin spring
- Java
- CloudWatch
- kotlin
- AI
- MySQL
- APM
- 정보처리기사 실기 기출문제
- mysql 튜닝
- 정보처리기사실기 기출문제
- 공부
- Pinpoint
- kotlin coroutine
- aws
- Kubernetes
- 티스토리챌린지
- Elasticsearch
- CKA
- AWS EKS
- Linux
- Spring
- 코틀린 코루틴의 정석
- Today
- Total
피터의 개발이야기
[kotlin] 코틀린 코루틴의 정석 - 무제한 디스패처(Unconfined Dispatcher) 본문
[kotlin] 코틀린 코루틴의 정석 - 무제한 디스패처(Unconfined Dispatcher)
기록하는 백앤드개발자 2024. 6. 14. 10:10
ㅁ 들어가며
ㅇ 코틀린 코루틴의 정석 책을 보고 정리한 글입니다.
11장 코루틴의 심화 - 무제한 디스패처(Unconfined Dispatcher)
ㅇ 무제한 디스패처는 코루틴을 자신을 실행시킨 스레드에서 바로 실행되도록 한다.
ㅇ 호출된 스레드와 상관없기 때문에 무제한적으로 실행하기 때문에 무제한 디스패처라고 부른다.
자신을 실행 시킨 스레드에서 즉시 실행
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis()
// Dispatchers.Unconfined 사용
launch(Dispatchers.Unconfined) {
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] launch 코루틴 실행 스레드는 ")
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] launch 코루틴이 main에 실행되어 같은 main이 된다.")
}
}
/*
[main @coroutine#2][실행시간: 2ms] launch 코루틴 실행 스레드는
[main @coroutine#2][실행시간: 15ms] launch 코루틴이 main에 실행되어 같은 main이 된다.
*/
ㅇ Dispatchers.Unconfined은 자신을 실행 시킨 스레드에서 즉시 실행된다.
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis()
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 메인 작업 실행")
launch(Dispatchers.Unconfined) { // Dispatchers.Unconfined를 사용해 실행되는 코루틴
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 서브 작업 실행")
}
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 다시 메인 작업 실행")
}
/*
[main @coroutine#1][실행시간: 1ms] 메인 작업 실행
[main @coroutine#2][실행시간: 17ms] 서브 작업 실행
[main @coroutine#1][실행시간: 18ms] 다시 메인 작업 실행
*/
ㅇ 비동기처리를 위해 스레드를 Dispatcher가 할당하지만, 즉시 실행할 경우 마치 동기처리처럼 순서가 보장될 수도 있다.
ㄴ 실시간으로 바로 이루어야 할 Job에 맞는 Dispatcher이다.
ㅇ 이런 점에서 CoroutineStart.UNDISPATCHED 옵션과 유사하지만 일시 중단 후 다시 할당되는 스레드에 차이가 날 수 있다.
CoroutineStart.UNDISPATCHED와 Dispatchers.Unconfined의 차이
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis()
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 메인 작업 실행")
launch(start = CoroutineStart.UNDISPATCHED) { // CoroutineStart.UNDISPATCHED가 적용된 코루틴
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] CoroutineStart.UNDISPATCHED 작업 실행")
delay(100L)
// CoroutineStart.UNDISPATCHED은 자신이 실행되는 CoroutineDispatcher 객체를 사용한다.
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] CoroutineStart.UNDISPATCHED 작업 재할당해도 나는 main이다.")
}.join()
launch(Dispatchers.Unconfined) { // Dispatchers.Unconfined를 사용해 실행되는 코루틴
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] Dispatchers.Unconfined 작업 실행")
delay(100L)
// Dispatchers.Unconfined는 자신을 재개시킨 스레드가 할당된다.
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] Dispatchers.Unconfined 작업 재할당하면...")
}
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 다시 메인 작업 실행")
}
/*
[main @coroutine#1][실행시간: 0ms] 메인 작업 실행
[main @coroutine#2][실행시간: 18ms] CoroutineStart.UNDISPATCHED 작업 실행
[main @coroutine#2][실행시간: 125ms] CoroutineStart.UNDISPATCHED 작업 재할당해도 나는 main이다.
[main @coroutine#3][실행시간: 127ms] Dispatchers.Unconfined 작업 실행
[main @coroutine#1][실행시간: 128ms] 다시 메인 작업 실행
[kotlinx.coroutines.DefaultExecutor @coroutine#3][실행시간: 232ms] Dispatchers.Unconfined 작업 재할당하면...
*/
ㅇ CoroutineStart.UNDISPATCHED은 자신이 실행되는 CoroutineDispatcher 객체를 사용한다.
ㅇ Dispatchers.Unconfined는 자신을 재개시킨 스레드가 할당된다.
중단 후 재개하는 스레드에서 실행
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis()
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 메인 작업 실행")
launch(Dispatchers.Unconfined) { // Dispatchers.Unconfined를 사용해 실행되는 코루틴
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 서브 작업 실행")
delay(100L)
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 서브 작업 실행")
}
println("[${Thread.currentThread().name}][${getRunTime(startTime)}] 다시 메인 작업 실행")
}
/*
[main @coroutine#1][실행시간: 0ms] 메인 작업 실행
[main @coroutine#2][실행시간: 14ms] 서브 작업 실행
[main @coroutine#1][실행시간: 19ms] 다시 메인 작업 실행
[kotlinx.coroutines.DefaultExecutor @coroutine#2][실행시간: 120ms] 서브 작업 실행
*/
ㅇ 위의 코드에 delay를 추가하여 스레드 재할당을 유도하였을 때 kotlinx.coroutines.DefaultExecutor가 할당되었다.
ㅇ Dispatchers.Unconfined은 일시 중단 후 재개 시키는 스레드에서 즉시 실행된다.
ㅇ 이로 인해 Dispatchers.Unconfined를 사용해 실행된 코루틴은 동작을 예측하기 어렵다.
ㅁ 함께 보면 좋은 사이트
'Programming > Kotlin' 카테고리의 다른 글
[Kotlin] Ktor 샘플 프로젝트 생성과정, 10분 미만 (0) | 2024.06.24 |
---|---|
Ktor란? (0) | 2024.06.19 |
[kotlin] 코틀린 코루틴의 정석 - 코루틴의 동작 원리(Coroutine과 Continuation) (0) | 2024.06.13 |
[kotlin] 코틀린 코루틴 디버깅 옵션설정 방법 (0) | 2024.06.12 |
[kotlin] 코틀린 코루틴의 정석 - CoroutineScope의 start 옵션 (0) | 2024.06.10 |