Jobs and awaiting childern

참치돌고래·2022년 12월 1일
0
post-custom-banner

parent-child 관계에서 동시성
1. children은 parent로부터 context를 상속받는다
2. perent는 childern이 끝날 때까지 suspend된다.
3. parent가 취소되면 child의 모든 coroutine은 취소된다.
4. children의 destory되면 parent도 destory된다.

2,3,4는 Job 에 밀접한 관계를 가지고 있다.

Job

job은 인터페이스이며, job을 통해 coroutine 취소, 상태 추적 등을 할 수 있다.

  • Active : job이 실행되는 상태. 대부분 coroutine이 실행되면 ACTIVE상태를 띄고 있다.
  • Completing : parent 실행이 끝나고 child들이 끝나길 기다리는 상태
  • Completed : child가 다 끝난 상태
  • Cancelling : 실행중일 때, job이 취소되거나 실패했을 때의 상태
  • Cancelled : Cancelling 상태 이후, connection 종료나 resource free 와 같은 후작업을 마친 상태

각 job들을 생성해 active, new등의 상태를 출력해보자

suspend fun main() = coroutineScope {
    val job = Job()
    println(job)
    job.complete()
    println(job)

    val activeJob = launch {
        delay(1000)
    }
    println(activeJob)
    activeJob.join()
    println(activeJob)

    val lazyJob = launch(start = CoroutineStart.LAZY) {
        delay(1000)
    }
    println(lazyJob)
    lazyJob.start()
    println(lazyJob)
    lazyJob.join()
    println(lazyJob)
}

output

JobImpl{Active}@5b6f7412
JobImpl{Completed}@5b6f7412
StandaloneCoroutine{Active}@2b05039f
StandaloneCoroutine{Completed}@2b05039f
LazyStandaloneCoroutine{New}@13ae1124
LazyStandaloneCoroutine{Active}@13ae1124
LazyStandaloneCoroutine{Completed}@13ae1124

job들 역시 parent를 기반으로 job들을 생성한다.

Job factory function

job은 coroutine 없이 생성 가능하다. 이렇게 생성된 job들은 context처럼 쓰이곤 한다.
(많은 coroutine들의 parent 역활로 생각)

suspend fun main() = coroutineScope {
    val job = Job()
    launch(job) {
        delay (1000)
        println("Text1")
    }
    launch(job) {
        delay(1000)
        println("Text2")
    }
    //job.join() 다른 coroutine 들이 사용되기를 기다림 
    job.children.forEach { it.join() }
} 

앞서 말했듯이 job은 interface라 생성자를 통해서 객체를 생성하지 못한다.
그러나 우리는 생성자를 사용하여 객체를 생성하는 것처럼 사용하고 있다.

public fun Job(parent: Job? = null) : CompletableJob

위의 코드와 같이 fake 생성자 를 통해서 생성자처럼 객체를 생성하고
반환하는 값 역시 Job이 아니라 CompletableJob 이다.

profile
안녕하세요
post-custom-banner

0개의 댓글