훌륭한 개발자가 되기 위하여
코루틴 제어 본문
코루틴 순차 처리
토큰을 받아서 업데이트 한 후 네트워크 요청을 해야한다고 가정했을 때, 업데이트 되기 전에 네트워크 요청이 되면 권한 없음과 같은 오류가 발생할 수 있다.
만약 A 코루틴이 완료된 후에 B 코루틴이 실행되야 한다면, B 코루틴이 실행되기 전에 A 코루틴에 대해 join 함수를 호출하면 된다.
이 때, Job 객체의 join 함수를 사용하면 코루틴 순차 처리가 가능하다.
fun main() = runBlocking<Unit> {
val job1 = launch(Dispatchers.IO) {
println("작업 1")
delay(1000L)
println("작업 2")
}
job1.join()
val networkCallJob = launch(Dispatchers.IO) {
println("네트워크 요청")
}
}
Join 함수를 사용하면 join 함수의 대상이 된 코루틴이 완료될 때까지 join 함수를 호출한 코루틴이 일시 중단된다.
👉 runBlocking 코루틴이 job1이 완료될 때까지 일시 중단된다.
joinAll() : 인자로 받은 job이 모두 완료될 때까지 대기
joinAll(job1, networkCallJob)
joinAll 내부 코드는 아래와 같다.
public suspend fun joinAll(vararg jobs: Job): Unit = jobs.forEach { it.join() }
jobList도 가능하다. 👉 listOf(job1, networkCallJob).joinAll()
지연 코루틴
👉 즉시 실행 요청되지 않는 코루틴
launch 함수의 start인자로 CoroutineStart.LAZY를 넘기면 된다.
fun main() = runBlocking<Unit> {
val lazyJob = launch(start = CoroutineStart.LAZY) {
...
}
}
이대로 실행하면 출력이 되지 않음
👉 지연 코루틴은 start 함수나 join함수로 호출하면 실행된다.
lazyJob.start() or lazyJob.join()
코루틴 취소
코루틴 실행 도중, 실행할 필요가 없는 경우 즉시 취소해야 한다.
👉 취소하지 않으면 코루틴이 스레드를 계속 사용해서 성능 저하가 발생한다.
job.cancel()
cancel 함수는 코루틴을 곧바로 취소하지 않고, 취소 확인용 플래그를 ‘취소 요청됨’으로 바꾸는 역할만 한다.
👉 취소가 언제되는지 확실하지 않기 때문에 cancel 함수를 사용하는 것은 순차성 관점에서 중요한 문제를 가진다.
해결방법
cancelAndJoin() : 취소 요청한 후 취소가 완료될 때까지 호출 코루틴을 일시 중단
👉 delay로 취소 확인 시점을 만드는 것 대신 Thread.sleep을 사용하면 Thread가 중단되므로 효과 없음
코루틴 취소 확인 시점
- 일시 중단 시점
- 코루틴이 실행을 대기하는 시점
취소 확인 시점 만들기
- delay 함수
- 특정 시간만큼 코루틴을 일시 중단하게 만든다.
- 일시 중단 시점에 코루틴의 취소가 확인돼 취소된다.
- 불필요하게 작업을 지연시켜 성능 저하가 발생한다.
- 특정 시간만큼 코루틴을 일시 중단하게 만든다.
- yield 함수
- yield 함수를 호출한 코루틴은 자신이 사용하던 스레드를 양보한다.
👉 스레드를 양보한 후 곧바로 재개 요청되기 때문에 delay 함수보다 효율적
👉 재개 시에는 CoroutineDispatcher에 의해 다시 스레드로 보내지는 과정을 거치기 때문에 비효율적이다.
3. CoroutineScope.isActive
코루틴에 취소가 요청되었는지 확인할 수 있다.
👉 코루틴에 취소가 요청되면 isActive가 false 된다.
코루틴의 상태
- 생성(New)
- 실행중(Active)
- 실행 완료중(Completing)
- 부모 코루틴의 모든 코드가 실행됬지만, 자식 코루틴이 실행 중인 경우 부모 코루틴이 갖는 상태
- 부모 코루틴이 더 이상 실행할 코드가 없더라도 자식 코루틴이 모두 완료될 때까지 기다리는데 이때 실행 완료 중 상태에 머무른다.
- 자식 코루틴이 모두 완료되면 부모 코루틴은 자동으로 실행 완료 상태로 전환된다.
- 실행 완료(Completed)
- 취소 중(Cancelling)
- 취소 완료(Cancelled)
job 객체를 출력하면 코루틴의 상태가 나온다.
Job 객체의 상태 변수
- isActive : 코루틴이 활성화 되어 있는지 여부. ‘실행 중’ 상태일 때 true 반환
- isCancelled : 코루틴에 취소가 요청됬는지 여부. cancel 함수가 요청되기만 하면 true를 반환하므로 취소 중인 상태도 포함
- isCompleted : 코루틴이 완료되었는지 여부. 코루틴이 완료되거나 취소 완료되면 true 반환
👉 취소 중일 때는 코루틴은 계속 실행되지만 isActive는 false가 출력됨
코루틴 상태 | isActive | isCancelled | isCompleted |
생성 | false | false | false |
실행 중 | true | false | false |
실행 완료 중 | true | false | false |
실행 완료 | false | false | true |
취소 중 | false | true | false |
취소 완료 | false | true | true |
'안드로이드' 카테고리의 다른 글
CoroutineContext란 (0) | 2025.01.10 |
---|---|
코루틴으로부터 결과 수신 받기 (0) | 2025.01.08 |
스레드 기반 작업의 한계, Coroutine Dispatcher (0) | 2025.01.06 |
[Android] Ktlint적용하기 (0) | 2024.10.29 |
[Android | Kotlin] 안드로이드 기본 앱과 연동하기 (1) | 2024.01.03 |