launch
는 실해중인 코루틴을 취소하는데 사용하는 Job
객체를 반환함.import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancel() // Job을 cancel한다.
job.join() // Job의 실행(취소)이 완료될 때까지 기다린다.
// job.cancelAndJoin()
println("main: Now I can quit.")
}
cancel
: 해당 범위(코드블록)의 코루틴을 취소함.
IllegalStateException
이 발생함.join
: 코루틴의 동작이 완료될 때 까지 대기함.
cancelAndJoin
: cancel
과 join
을 결합한 함수임.cancel을 하고 join을 안해준 경우엔 cancel 이후의 코드가 코루틴이 완전히 종료되기 전에
실행될 가능성이 있음.
kotlin.coroutines
패키지의 모든 일시 중단 함수들은 취소가 가능함.
CancellationException
을 발생시킴.
cancel
함수 호출 시 발생함.CancellationException
예외는 일시 중단 함수가 있을 경우에만 발생함.CancellationException
예외는 코루틴 라이브러리에서 catch
하고, 코루틴을 종료시킴.
try-catch
를 사용하면 됨.import kotlinx.coroutines.*
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // 계산 루프, CPU를 낭비한다
// 1초에 두 번 메세지를 출력한다.
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // 약간의 시간 동안 delay 한다
println("main: I'm tired of waiting!")
job.cancelAndJoin() // Job을 취소하고 실행이 완료될 때까지 기다린다.
println("main: Now I can quit.")
}
// 이 코드는 취소했음에도 I'm sleeping이 출력되는 이유는 cancel호출시 중단지점이 없음.
출력결과 :
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
job: I'm sleeping 3 ...
job: I'm sleeping 4 ...
main: Now I can quit.
위 처럼 취소를 했음에도, I'm sleeping이 계속 출력됨.
위와 같은 문제는 CancellationException을 catch하고 다시 throw 하지 않는 경우에도 발생함.
try {
...
} catch (e: CancellationException) {
throw e
}
yield
함수// 명시적으로 취소 상태를 확인하는 예시
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // 취소 가능한 computation loop
// 1초에 두 번 메세지를 출력한다.
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
isActive
는 CoroutineScope
객체를 통해 코루틴 내부에서 사용할 수 있는 확장 프로퍼티임.