코루틴 영역과 구조적 동시성
코루틴은 기본적으로 전역 영역(Global Scope)에서 실행됩니다. 이는 코루틴의 생명주기가 어플리케이션 전체의 생명주기에 의해 제약되는 것을 의미합니다. 그러나 때로는 특정 연산을 수행하는 동안에만 코루틴이 실행되길 원할 수 있습니다. 이를 위해 특정한 코루틴 영역을 만들어 사용할 수 있습니다.
구조적 동시성은 부모-자식 관계를 가진 코루틴이 서로 연관되어 실행되는 개념입니다. 특정 코루틴을 다른 코루틴의 문맥에서 실행하면 부모-자식 관계가 형성되어 자식의 실행이 모두 완료되어야 부모가 끝날 수 있습니다.
import kotlinx.coroutines.*
import java.lang.System.*
suspend fun main() {
runBlocking{
println("Parent task started")
launch{
println("Task A started")
delay(100)
println("Task A finished")
}
launch{
println("Task B started")
delay(100)
println("Task B finished")
}
delay(100)
println("Parent task finished")
}
println("Shutting down...")
}
// 결과
// Parent task started
// Task A started
// Task B started
// Parent task finished
// Task A finished
// Task B finished
// Shutting down...
이 코드는 runBlock{} 으로 최상위 코루틴을 시작하고 현재 CoroutineScope 인스턴스 안에서 launch를 호출해 두 개의 자식 코루틴을 시작합니다. 결과를 살펴보면 runBlocking()이 메인 스레드를 블럭하고 있기 때문에 부모 스레드가 끝나야 메인 스레드의 블럭이 풀리고 마지막 메시지가 출력됩니다.
또한 coroutineScope() 호출로 코드 블럭을 감싸면 커스텀 영역을 도입할 수 있습니다. coroutineScope는 자식들이 완료되기 전까지 종료 되지 않습니다. runBlocking과 유사하지만 가장 큰 차이는 현재 스레드를 Block 시키지 않는다는 점입니다. 아래 예제는 두 자식 코루틴의 실행이 끝날 때 까지 coroutineScope 호출이 일시 중단되므로 "Custom Scope finished" 메시지는 마지막에 표시됩니다.
import kotlinx.coroutines.*
import java.lang.System.*
suspend fun main() {
runBlocking{
println("Custom Scope started")
coroutineScope{
launch{
delay(100)
println("Task 1 finished")
}
launch{
delay(100)
println("Task 2 finished")
}
}
println("Custom Scope finished")
}
}
// 결과
// Custom Scope started
// Task 1 finished
// Task 2 finished
// Custom Scope finished
코루틴 문맥 (Coroutine Context)
코루틴 문맥(Coroutine Context)은 코루틴이 실행되는 환경에 관련된 정보를 담고 있는 개념입니다. 코루틴은 항상 특정 문맥에서 실행되며, 이 문맥은 CoroutineContext 객체에 의해 정의됩니다. CoroutineContext는 키-값 쌍의 불변 컬렉션으로, 다양한 정보와 설정이 들어있습니다. 코루틴 문맥의 중요한 부분 중 하나는 스레드 풀을 나타내는 것입니다. 기본적으로 CommonPool이라는 공통 스레드 풀이 지정되어 있어 코루틴이 실행될 때 이 풀에서 스레드를 가져와 작업을 수행합니다.
또한, CoroutineContext는 여러 가지 다른 속성도 가질 수 있습니다. 예를 들어, 예외 처리, 부가적인 정보, 그리고 다른 문맥을 결합하는 기능 등이 있습니다. 아래 코드는newSingleThreadContext를 사용하여 새로운 스레드 컨텍스트를 만들고
+ 연산자를 통해 여러 속성을 결합하여 사용했습니다.
코루틴 문맥은 코루틴이 실행되는 환경을 제어하고 조절하는데 중요한 역할을 합니다.
import kotlinx.coroutines.*
import java.lang.System.*
// 예시: CoroutineContext의 여러 속성
import kotlinx.coroutines.*
suspend fun main() {
runBlocking {
val customContext = newSingleThreadContext("MyThread")
launch(customContext + CoroutineName("MyCoroutine")) {
println("Running on ${Thread.currentThread().name}")
}
}
}
// 결과 : Running on MyThread @MyCoroutine#2
'KOTLIN' 카테고리의 다른 글
StateFlow가 중복된 값을 반환하지 않는 이유(DistinctUntilChanged) (0) | 2024.03.08 |
---|---|
[Kotlin] LiveData 대신 StateFlow 사용하기 (1) | 2024.01.15 |
[Kotlin] Coroutine Flow (0) | 2024.01.15 |
[KOTLIN IN DEPTH] Kotlin Coroutine Concurrency 2 (0) | 2023.12.18 |
[Kotlin] 코틀린의 Null 안정성 (0) | 2023.12.16 |