Recent Posts
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 달인막창
- 코루틴 빌더
- VARCHAR (1)
- 개성국밥
- 깡돼후
- 겨울 부산
- PersistenceContext
- 오블완
- terminal
- Spring Batch
- mp4fpsmod
- tolerated
- 티스토리챌린지
- JanusWebRTCServer
- Value too long for column
- 자원부족
- python
- 헥사고날아키텍처 #육각형아키텍처 #유스케이스
- JanusWebRTC
- kotlin
- 코루틴 컨텍스트
- vfr video
- JanusWebRTCGateway
- PytestPluginManager
- taint
- preemption #
- k8s #kubernetes #쿠버네티스
- JanusGateway
- table not found
- pytest
Archives
너와 나의 스토리
[Coroutine] Async vs launch / Deffered vs Job / CoroutineContext와 Dispatcher / 일시중단함수 본문
Programming Language/Kotlin
[Coroutine] Async vs launch / Deffered vs Job / CoroutineContext와 Dispatcher / 일시중단함수
노는게제일좋아! 2022. 10. 18. 21:02반응형
kotlinx.coroutines.CoroutineScope.async
- async는 사실상 launch와 같은 일을 한다.
- 유일한 차이는 launch가 Job을 반환하는 반면 async는 Deffered를 반환한다는 점뿐이다.
- 심지어 Deffered는 Job을 상속한 클래스이기 때문에 launch 대신 async를 사용해도 아무 문제 없다.
- async는 코드 블록을 비동기로 실행할 수 있다.
- async가 반환하는 Deffered의 await을 사용해서 코루틴이 결과 값을 내놓을 때까지 기다렸다가 결과값을 얻어낼 수 있다.
Deffered vs Job
- Job
- 타입 파라미터가 없음
- Deffered
- 타입 파라미터가 있는 제네릭 타입
- Deffered 안에는 await() 함수가 정의되어 있다.
- Deffered의 타입 파라미터는 Deffered 코루틴이 계산을 하고 돌려주는 값의 타입이다.
예제
- async / await을 사용해서 1부터 3까지 수를 더해보자.
fun sumAll() {
runBlocking {
val cur = Instant.now()
val d1 = async {
delay(1000L);
1
}
log("after async(d1)")
val d2 = async {
delay(2000L);
2
}
log("after async(d2)")
val d3 = async {
delay(3000L);
3
}
log("after async(d3)")
log("1+2+3 = ${d1.await() + d2.await() + d3.await()}")
val duration = Duration.between(cur, Instant.now())
log("after await all & add - duration: $duration")
}
}
fun main() {
log("main() started.")
sumAll()
}
- 병렬로 작동하여 위 작업을 하는 동안 총 3초정도 걸린 것을 확인할 수 있다.
- PT prefix 의미: Period of Time
- 그럼에도 불구하고 스레드를 여럿 사용하는 병렬 처리와 달리 모든 async 함수들이 메인 스레드 안에서 실행됨을 볼 수 있다.
CoroutineContext와 Dispatcher
- launch, async 등은 모두 CoroutineScope의 확장 함수다.
- CoroutineScope에는 CoroutineContext 타입의 필드 하나만 들어있다.
- CoroutineScope는 CoroutineContext 필드를 launch 등의 확장 함수 내부에서 사용하기 위해 매개체 역할만을 담당한다.
- CoroutineContext는 실제로 코루틴이 실행 중인 여러 작업(Job)과 디스패처(Dispatcher)를 저장하는 일종의 맵이라고 할 수 있다.
- 코틀린 런타임은 이 CoroutineContext를 사용해서 다음에 실행할 작업을 선정하고, 어떻게 스레드에 배정할지에 대한 방법을 결정한다.
fun coroutineTest(){
runBlocking {
launch{ // 부모 context 사용
log("main runBlocking: I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Unconfined){ // 특정 스레드에 종속되지 않음
log("Unconfined : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Default){ // 특정 스레드에 종속되지 않음
log("Default : I'm working in thread ${Thread.currentThread().name}")
}
launch(newSingleThreadContext("MyOwnThread")){ // 새 스레드를 사용
log("newSingleThreadContext : I'm working in thread ${Thread.currentThread().name}")
}
}
}
fun main() {
log("main() started.")
coroutineTest()
}
- 같은 launch를 사용하더라도 전달하는 컨텍스트에 따라 서로 다른 스레드상에서 코루틴이 실행됨을 알 수 있다.
코루틴 빌더
- Kotlinx-couroutines-core 모듈이 제공하는 코루틴 빌더
- launch
- async
- runBlocking
- produce
- 정해진 채널로 데이터를 스트림으로 보내는 코루틴을 만든다.
- actor
- 정해진 채널로 메시지를 받아 처리하는 액터를 코루틴으로 만든다.
- 코루틴 빌더: 코루틴을 만들어주는 함수.
일시 중단 함수
- Kotlinx-couroutines-core 모듈의 최상위에 정의된 일시 중단 함수
- delay()
- yield()
- withContext
- 다른 컨텍스트로 코루틴을 전환.
- withTimeout
- 코루틴이 정해진 시간 안에 실행되지 않으면 예외를 발생시키게 함.
- withTimeutOrNull
- 코루틴이 정해진 시간 안에 실행되지 않으면 null을 결과로 돌려준다.
- awaitAll
- 모든 작업의 성공을 기다린다. 작업 중 어느 하나가 예외로 실패하면 awaitAll도 그 예외로 실패한다.
- joinAll
- 모든 작업이 끝날 때까지 현재 작업을 일시 중단시킨다.
suspend 키워드와 코틀린의 일시 중단 함수 컴파일 방법
- 코루틴이 아닌 일반 함수 속에서 delay()나 yield()를 쓰면 컴파일 수준에서 사용이 금지된다.
- 코틀린은 코루틴 지원을 위해 suspend라는 키워드를 지원한다.
- 함수 정의의 fun 앞에 suspend를 넣으면 일시 중단 함수를 만들 수 있다.
suspend fun yieldThreeTimes() {
log("1")
delay(1000L)
yield()
log("2")
delay(1000L)
yield()
log("3")
}
fun suspendExample() {
GlobalScope.launch { yieldThreeTimes() }
}
반응형
'Programming Language > Kotlin' 카테고리의 다른 글
Kotlin coding convention 정리 (0) | 2022.07.01 |
---|---|
[Kotlin] takeIf & takeUnless (0) | 2022.06.19 |
[Kotlin] 재귀 함수를 꼬리 재귀 함수로 변환하여 최적화하는 방법 (tailrec 사용) (0) | 2021.09.10 |
[Kotlin] 재귀 함수 값(val) 사용하기, 재귀 함수 초기화 문제 해결 by lazy (0) | 2021.09.06 |
[Kotlin] 재귀 함수의 꼬리 호출 제거(TCE): tailrec 키워드 (0) | 2021.09.06 |
Comments