kotlin 을 기본적으로 부모의 context들이 child에 영향을 줍니다.
즉, child 는 parent로부터 context를 상속받습니다.
아래와 같이 log
확장함수를 생성하고
main
이라는 이름으로 main함수 안에서 coroutine
을 실행합니다.
fun CoroutineScope.log(msg: String) {
val name = coroutineContext[CoroutineName]?.name
println("[$name] $msg")
}
fun main() = runBlocking(CoroutineName("main")) {
log("started")
val v1 = async {
delay(500)
log("Running async")
}
this.launch {
delay(1000)
log("Running in launch")
}
log("The answer is ${v1.await()}")
}
output
[main] started
[main] Running async
[main] The answer is 42
[main] Running in launch
위에서 설명한 것과 같이 async
와 launch에서도
main`이라는 이름의 로그가 출력되는 것을 확인할 수 있습니다.
child
가 parent
를 상속한다면 override
역시 가능합니다.
각 async
와 launch
의 coroutine이름을 각각 c1
과 c2
로 재정의하겠습니다.
fun CoroutineScope.log(msg: String) {
val name = coroutineContext[CoroutineName]?.name
println("[$name] $msg")
}
fun main() = runBlocking(CoroutineName("main")) {
log("started")
val v1 = async(CoroutineName("c1")) {
delay(500)
log("Running async")
42
}
this.launch(CoroutineName("c2")) {
delay(1000)
log("Running in launch")
}
log("The answer is ${v1.await()}")
}
output
[main] started
[c1] Running async
[main] The answer is 42
[c2] Running in launch
기본적으로 coroutine context는 위에서 본 것과 같이
defualtContext + parentContext + childContext
와 같이 계산할 수 있습니다.
각 속성들은 map
과 같은 자료구조에 저장되며, 같은 key
로 저장되면,
단순하게 가장 최근 값이 이전 값을 대신합니다.