구조화된 동시성
코루틴 스코프는 구조화된 동시성을 가진다고 했다.
- 자식은 부모로부터 컨텍스트를 상속받는다.
- 부모는 모든 자식이 작업을 마칠 때까지 기다린다.
- 부모 코루틴이 취소되면 자식 코루틴도 취소된다.
- 자식 코루틴에서 에러가 발생하면, 부모 코루틴 또한 에러로 소멸한다.
자식이 부모로부터 컨텍스트를 물려받는 건 코루틴 빌더의 가장 기본적인 특징이다.
이 구조화된 동시성의 특징 중 세 가지는 Job 컨텍스트와 관련이 있다.
Job은 코루틴을 취소하고, 상태를 파악하는 등 다양하게 사용될 수 있다.
Job?
Job은 수명을 가지고 있으며 취소가 가능하다. Job은 인터페이스이지만 구체적인 사용법과 상태를 가지고 있다는 점에서 추상 클래스처럼 다룰 수도 있다.
Job의 수명은 상태로 나타낸다.
`Active`상태 : 잡이 실행되고 코루틴을 잡을 수행. 잡이 코루틴이 빌더에 의해 생성되었을 때 코루틴의 본체가 실행되는 상태이다. 이 상태에서 자식 코루틴을 시작할 수 있다. 대부분의 코루틴은 `Active`상태로 시작된다.
`New` 상태 : 지연 시작되는 코루틴만 `New` 상태에서 시작된다. `New` 상태인 코루틴이 `Active` 상태가 되려면 작업이 시작되어야 한다.
실행이 완료되면 상태는 `Completing`으로 바뀌고 자식들을 기다린다.
자식들의 실행도 모두 끝났다면 Job은 마지막 상태인 `Completed`로 바뀐다.
만약 Job이 실행 도중에 취소되거나 실패하게 되면 `Cancelling`상태로 가게 된다. 여기서 연결을 끊거나 자원을 반납하는 등의 후처리 작업을 할 수 있다.
후처리 작업이 완료되면 잡은 `Cancelled` 상태가 된다.
Job의 상태를 확인하기 위해 `isActive` , `isCompleted`, `isCancelled` 프로퍼티를 사용하면 된다.
코루틴 빌더의 Job
코루틴 빌더는 부모의 Job을 기초로 자신들의 Job을 생성한다.
Job은 코루틴이 상속하지 않는 유일한 코루틴 컨텍스트이다.
모든 코루틴은 자신만의 Job을 생성하며 인자 또는 부모 코루틴으로부터 온 Job은 새로운 Job의 부모로 사용된다.
부모 Job은 자식 Job 모두를 참조할 수 있으며, 자식 또한 부모를 참조할 수 있다. Job을 참조할 수 있는 부모-자식 관계가 있기 때문에 코루틴 스코프 내에서 취소와 예외 처리 구현이 가능하다.
새로운 Job 컨텍스트가 부모의 Job을 대체하면 구조화된 동시성의 작동 방식은 유효하지 않다.
다음 코드에서 부모와 자식 사이에 아무런 관계가 없기 때문에 부모가 자식 코루틴을 기다리지 않는다. 자식은 인자로 들어온 Job을 부모로 사용하기 때문에 `runBlocking`과는 아무런 관련이 없게 된다.
fun main(): Unit = runBlocking {
launch(Job()) {
delay(1000)
println("이게 보이면 그건 환상")
}
println("완료")
}
코루틴이 자신만의 독자적인 잡을 가지고 있으면 부모와 아무런 관계가 없다고 할 수 있다.
자식은 다른 컨텍스트를 상속받게 되지만, 부모-자식 관계가 정립되지 못하고, 구조화된 동시성을 잃게 된다.
기다리기
Job은 코루틴이 완료될 때까지 기다리는 데 사용될 수 있다.
이때, `join` 메서드를 사용한다. `join`은 지정한 잡이 `Completed`나`Cancelled`와 같은 마지막 상태에 도달할 때까지 기다리는 중단 함수이다.
`join`을 쓰게 되면, 모든 자식이 마지막 상태가 될 때까지 기다리는데 활용할 수 있다.
다음은 `join`을 사용했을 때와 사용하지 않았을 때 각각 실행 결과이다.
fun main(): Unit = runBlocking {
val job1 = launch {
delay(1000)
println("job1")
}
val job2 = launch {
delay(1000)
println("job2")
}
job1.join()
job2.join()
println("완료")
}
참고자료
마르친 모스카와(2023), 코틀린 코루틴 Kotlin Coroutines : Deep Dive - 안드로이드 및 백엔드 개발자를 위한 비동기 프로그래밍, 인사이트
https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/
'Kotlin Coroutines' 카테고리의 다른 글
[Kotlin Coroutines] 디스패처 (1) | 2024.05.27 |
---|---|
[Kotlin Coroutines] 코루틴 스코프 함수 (0) | 2024.05.20 |
[Kotlin Coroutines] 코루틴 예외 처리 (0) | 2024.05.17 |
[Kotlin Coroutines] 코루틴 취소 (0) | 2024.05.17 |
[Kotlin Coroutines] 코루틴 빌더에 대해 알아보자 (0) | 2024.05.10 |