Job ?
우리는 launch라는 코루틴빌더를 이용해 코루틴을 생성하면 launch는 Job객체를 반환 해준다고 배웠다.
이때 Job은 무슨 역할을 하는 건지 알아보겠습니다.
Job 상태변수
Job객체에는 3개의 상태변수가 있다.
isActive = Job이 실행중인지 여부를 표시
isCancelled = Job Cancel이 요청되었는지 여부를 표시
isCompleted = Job이 완료되었거나, cancel이 완료되었는지 표시
Job 메서드
자주쓰는 메서드를 알아보자.
start() : Job객체를 실행하는데 호출한 Thread를 Blocking 하지 않는 메서드.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch() {
delay(3000)
println("launch완료")
}
job.start()
}
위의 코드는 아무런 출력도 하지 않는다.
IOThread에서 작업이 끝나는걸 MainThread에서 기다려줘야 하는데 start() 는 호출한 Tread를 Blocking 시키지 않는다.
그래서 바로 종료 되는거다.
join() : 호출한 Tread를 Blocking 시켜 실행 중인 Job이 종료될 때까지 기다린다.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch() {
delay(3000)
println("launch완료")
}
job.join()
}
위에 코드를 실행시켜보면 정상적으로 출력이 나오는걸 확인할 수 있다.
상황에 따라 골라 쓰면 될 거 같다.
특히 launch는 일반적으로 생성된 비동기 작업을 바로 실행 시킨다.
이를 필요할 때 실행시킬수 있도록 하는 것이 있는데
launch() 인자에 CoroutineStart.LAZY 를 넣으면 필요할 때 start() 와 join()으로 사용할 수 있게 된다.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch(start = CoroutineStart.LAZY) {
delay(1000)
println("launch완료")
}
delay(2000)
}
이 코드를 실행시켜보면 아무것도 나오지 않는다.
launch인자에 CoroutineStart.LAZY 를 넣어 필요할 때 실행되게 만들어 뒀기 때문이다.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch(start = CoroutineStart.LAZY) {
delay(1000)
println("launch완료")
}
// job.start() //아무것도출력안됨
job.join() //정상출력
}
cancel() : Job을 취소시켜야 할 상황이 올 수 있다. 이때 Job을 취소시키는 메서드.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch() {
delay(1000)
println("launch완료")
}
job.cancel()
delay(2000)
println("${job.isCancelled}")
println("${job.isCompleted}")
}
Job이 바로 실행되게 만들고 바로 cancel()로 취소 시킨다음 취소가 됐는지 2초를 기다리면 println("launch완료")가 나오지 않는걸 확인할 수 있다. 그리고 Job의 상태변수를 찍어서 취소요청이 왔는지, Job이 완료되었거나, 취소가 완료되었는지 확인한다.
getCancellationException() : Job의 취소원인을 출력해주는 메서드.
여러 가지 조건으로 취소시킬 때 무슨 이유로 취소되었는지 확인하고 싶을 때 사용한다.
cancel(안에 인자로 취소 이유를 적고)
Job.getCancellationException() 을 실행시키면 된다.
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch() {
delay(1000)
println("launch완료")
}
val a = 2
if(a == 1) {
job.cancel("a가 1이라 취소시켰어요.")
}
if(a == 2 ) {
job.cancel("a가 2라 취소시켰어요.")
}
delay(2000)
println("${job.getCancellationException()}")
println("${job.isCancelled}")
println("${job.isCompleted}")
}
invokeOncompletion() : calcel 동작 핸들링 하는 메소드
suspend fun main() {
val job = CoroutineScope(Dispatchers.IO).launch() {
delay(1000)
println("launch완료")
}
val a = 2
if(a == 1) {
job.cancel("a가 1이라 취소시켰어요.")
}
if(a == 2 ) {
job.cancel("a가 2라 취소시켰어요.")
}
delay(2000)
job.invokeOnCompletion {
when(it) {
is CancellationException -> println("Cancel")
null -> println("no error")
}
}
println("${job.isCancelled}")
println("${job.isCompleted}")
}
'Android-Kotlin > Coroutine' 카테고리의 다른 글
[Coroutine] launch란? 간단 사용법 - Kotlin (0) | 2022.06.25 |
---|---|
[Coroutine] Dispatcher 란? - Kotlin (0) | 2022.06.22 |
[Coroutine] CoroutineScope란? Kotlin (0) | 2022.06.22 |