Developing Myself Everyday

잡은 동시성 작업의 생명주기를 표현하는 객체이다. 잡을 사용하면 작업 상태를 추적하고 필요할 때 그 작업을 취소할 수 있다. 잡의 객체에는 3개의 상태변수가 있다.

 

  • isActive: 잡이 활성화 되었는지
  • isCancelled: 잡이 취소중이거나 취소 뒤었는지
  • isCompleted: 잡이 완료되거나 취소 되었는지

 

잡은 생성되자 마자 디폴트 상태인 활성화 상태가 된다. 잡을 생성할 때, CoroutineStart 타입의 파라미터를 지정해서 초기 상태를 지정할 수도 있다.

 

  • CoroutineStart.DEFAULT: 디폴트 동작이며 잡을 즉시 시작한다.
  • CoroutineStart.LAZY: 잡이 신규 상태가 되고 시작을 기다리게 된다.

 

다음의 예제를 보자

 

코드

fun main() {
    runBlocking {
        val job = launch(start = CoroutineStart.LAZY) {
            println("job 시작")
        }

        delay(100)

        println("job 준비중.....")
        job.start()
    }
}

 

결과

job 준비중.....
job 시작

 

위의 예제는 자식 코투틴의 시작을 부모 코루틴이 메시지를 호출한 뒤로 미룬다.

 

 


잡의 join() 메서드를 사용하면 조인 대상 잡이 완료될 때까지 현재 코루틴을 일시 중단시킬 수 있다. 다음의 예제는 부모 코투린의 메시지가 두 자식 메시지의 실행이 끝난 후에 출력되도록 한다.

 

 

코드

fun main() {
    runBlocking {
        val job = coroutineContext[Job.Key]!!

        val jobA = launch { println("jobA 실행") }
        val jobB = launch { println("jobB 실행") }

        jobA.join()
        jobB.join()

        println("실행중인 job의 개수 - " + job.children.count())
    }
}

 

결과

jobA 실행
jobB 실행
실행중인 job의 개수 - 0

 

 

 

 

잡의 취소


잡의 cancel() 메서드를 사용하면 잡을 취소할 수 있다.

 

fun main() {
    runBlocking {
        val job = GlobalScope.launch {
            var i = 1
            while (isActive)
                println("jobA ${i++} 번째 실행")
        }
        
        delay(100)

        job.cancel()
    }
}

 

위와 같이 사용하면 되는데 isActive를 통해 job의 상태를 확인해야 취소를 위해 위의 코루틴이 협력한다.

 

fun main() {
    runBlocking {
        val job = GlobalScope.launch {
            var i = 1
            while (true) {
                yield()
                println("jobA ${i++} 번째 실행")
            }
        }

        delay(100)

        job.cancel()
    }
}

 

위와 같이 yield()를 사용하는 방법도 있다. 이 메서드를 호출하면 실행 중인 잡을 일시 중단시켜서 자신을 실행 중인 스레드를 다른 코루틴에게 양보하게 된다.

 

profile

Developing Myself Everyday

@배준형

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!