728x90
Cancellation
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 취소
job.join() // job의 완료를 기다림.
println("main: Now I can quit.")
// 끝
}
- 코루틴을 사용할 경우 더이상 코루틴 동작이 필요하지 않은 경우 취소를 해줘야함 (자원 낭비가 발생)
- main()에서 job.cancel을 호출하면 다른 코루틴이 취소 되기 때문에 출력 금지됨
Cancellation is cooperative
fun main() = runBlocking {
// 시작
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // 연산 루프, CPU를 소비한다.
// 초당 두 번씩 메시지를 출력한다.
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // 조금 지연시킴
println("main: I'm tired of waiting!")
job.cancelAndJoin() // job을 취소하고 완료되기를 기다림
println("main: Now I can quit.")
// 끝
}
- 코루틴의 취소는 협조적이며, 코루틴의 모든 suspend 함수는 취소가 가능함
- 취소를 확인한후 CancellationException이 발생, 코루틴이 연산 작업인 경우에는 취소 여부를 확인하지 않으면 취소를 할 수 없음
연산 코드 취소
fun main() = runBlocking {
//시작
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // 취소 가능한 연산 루프
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancelAndJoin()
println("main: Now I can quit.")
// 끝
}
- isActive를 통하여 코루틴스코프 객체를 통해 연산 루프를 취소
- isActive는 job이 active 상태인지 체크 해줌
Closing resources with finally
fun main() = runBlocking {
// 시작
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
println("job: I'm running finally")
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancelAndJoin()
println("main: Now I can quit.")
// 끝
}
- try finally를 이용하여 코틀린이 취소될 때 정상적으로 최종작업을 진행
- finally는 리소스 해제 지역임, finally 블록에서 suspend함수를 사용하려고 하면 CancellationException 발생함
Non-cancellable block
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
withContext(NonCancellable) {
println("job: I'm running finally")
delay(1000L)
println("job: And I've just delayed for 1 sec because I'm non-cancellable")
}
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancelAndJoin()
println("main: Now I can quit.")
}
- 취소된 코루틴에서 suspend 함수를 사용해야하는 경우 withContext(NonCancellable)로 감싸서 사용이 가능함
'KOTLIN' 카테고리의 다른 글
[KOTLIN] 변수의 스코프 최소화 (이펙티브코틀린) (0) | 2022.06.18 |
---|---|
[KOTLIN] CONTEXT / DISPATCHER (0) | 2022.06.15 |
[KOTLIN] SUSPEND 함수 (0) | 2022.06.06 |
[KOTLIN] 코루틴 (0) | 2022.06.01 |
[KOTLIN] NULL SAFTY / NULL 처리방법 (0) | 2022.05.30 |