자식1, 2와 부모코루틴의 관계
225
작성한 질문수 7
본 강의를 모두 수강하였습니다! 코루틴에서 헷갈렸던 개념들을 알 수 있어서 좋았습니다!
본 코루틴 강의에서 자식과 부모 관계의 에러가 발생했을 때 에러 핸들링 하는 경우는 자식이 하나만 존재했을 때의 예시밖에 없어서 직접 2개를 가지고 실험을 해보았습니다!
먼저, 자식1이 취소가 됐을 때에는 취소예외가 발생했기 때문에 부모로 전파되지 않고, 그러므로 다른 자식2도 영향을 받지 않는다 라고 이해를 하고 있습니다!
하지만 자식1에서 취소가 아닌 예외가 발생했을 경우 부모로 전파되는 것으로 알고있고, 이 때 적절한 조치가 되지 않는다면 자식2까지 취소되는 것으로 알고있습니다!
따라서 다음과 같이 CoroutineExceptionHandler를 적용해보았습니다.
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception: $exception")
}
val parentJob = CoroutineScope(Dispatchers.Default).launch(handler) {
val job1 = launch {
println("Job 1 is running")
throw RuntimeException("Error in Job 1")
}
val job2 = launch {
println("Job 2 is running")
delay(1000)
println("Job 2 is completed")
}
job1.join()
job2.join()
}
parentJob.join()
println("Parent job is completed")
}Job 1 is running
Caught exception: java.lang.RuntimeException: Error in Job 1
Parent job is completed
결과는 자식1만 실행이되고, 거기서 Exception을 던졌는데, Job2는 취소되는것으로 보입니다..!
질문 1 ) 다음과 같이 try catch 로 전환하면 자식2의 취소가 발생하지 않는데, CoroutineExceptionHandler로는 자식2의 취소를 막을수는 없는 것일까요?
val job1 = launch {
println("Job 1 is running")
try {
throw RuntimeException("Error in Job 1")
} catch (e: RuntimeException) {
println("RuntimeException")
}
}질문 2) 강의내용에서는 SupervisorJob() 을 사용하면 부모 코루틴으로 예외가 전파되지 않는다고 해주셨는데, 다음 결과에서는 부모코루틴에 해당되는 CoroutineExceptionHandler 가 실행되는 것으로 보입니다. 하지만, 질문1에서 걱정하는 자식2의 취소로 이어지지 않고 있습니다. 이는 부모코루틴으로 예외가 전파되는 상황일까요?? 만일 전파되는 상황이라면 왜 질문1과는 다르게 자식2의 취소로 이어지지 않는 것일까요?
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception: $exception")
}
val parentJob = CoroutineScope(Dispatchers.Default).launch(handler) {
val job1 = launch(SupervisorJob()) {
println("Job 1 is running")
throw RuntimeException("Error in Job 1")
}
val job2 = launch {
println("Job 2 is running")
delay(1000)
println("Job 2 is completed")
}
job1.join()
job2.join()
}
parentJob.join()
println("Parent job is completed")
}Job 1 is running
Job 2 is running
Caught exception: java.lang.RuntimeException: Error in Job 1
Job 2 is completed
Parent job is completed
자바 -> 코틀린 강의부터 시작해서 코루틴 강의까지 너무 감사하게 잘 보고있습니다! 감사드립니다 🙂
답변 1
1
안녕하세요 성식님! 🙂 좋은 질문 주셔서 정말 감사드립니다! 🙏
결론부터 말씀드리면 CoroutineExceptionHandler 라는 이름이 마치 예외를 막아줄 것 처럼 느껴지지만, CoroutineExceptionHandler 은 예외에 대한 로직을 처리할 뿐 예외를 막지는 않습니다!
제가 코루틴에서 예외를 처리하는 방법을 소개해드리며, try - catch와 CoroutineExceptionHandler 을 같이 말씀드려서 조금 더 헷갈리셨을 수 있겠네요! 😭 (다른 점을 강조해둘 걸 그랬습니다!)
실제로 공식 문서의 설명을 보면
It is similar to Thread.uncaughtExceptionHandler. You cannot recover from the exception in the CoroutineExceptionHandler.
이라는 설명이 있는데요, CoroutineExceptionHandler 는 Thread.uncaughtExceptionHandler 와 비슷하고 핸들러 안에서 예외를 recover (=> 예외를 먹다, 막다 정도로 해석하면 될 것 같아요!) 할 수 없다고 되어 있습니다. 즉, try - catch는 특정한 예외를 막아 코루틴 안에서 예외가 발생하지 않은 것으로 간주하는 반면, CoroutineExceptionHandler 는 예외를 발생한 것으로 간주하되, 예외에 관한 로직을 핸들링 할 수 있는 방법인 셈이죠!
이 사실을 명확히 하고 질문 1, 2번을 보면 조금 더 명확해집니다.
[질문 1. 다음과 같이 try catch 로 전환하면 자식2의 취소가 발생하지 않는데, CoroutineExceptionHandler로는 자식2의 취소를 막을수는 없는 것일까요?]
CoroutineExceptionHandler로는 자식의 취소를 막을 수 없고 따라서 부모로 예외가 전파되어 다른 sibling coroutine도 취소가 이루어집니다!
[질문 2. 이는 부모코루틴으로 예외가 전파되는 상황일까요?? 만일 전파되는 상황이라면 왜 질문1과는 다르게 자식2의 취소로 이어지지 않는 것일까요?]
우선 예외가 발생했고, 해당 예외는 CoroutineExceptionHandler에 의해 핸들링이 된 상황입니다! 그리고 이제 원래대로 라면 부모로 예외를 전파 해야 하지만, SupervisorJob() 에 의해 부모로 전파는 되지 않습니다. 따라서 자식 코루틴이 중간에 종료되지는 않는 상황이에요!
답변이 도움이 되었으면 좋겠습니다. 또 언제든 궁금한 점 있으시면 편하게 질문 주세요!
감사합니다! 🙏
Dispatchers 별 차이점 관련 질문
0
91
1
코루틴과 가상 스레드의 차이가 궁금합니다.
1
307
2
Coroutine과 ThreadLocal관련 질문
0
152
2
선생님 강의를 듣고 크롤링에 코루틴을 적용해보고 있습니다. 그런데 코루틴이 하나만 나와서 동시처리가 안되는데 혹시 봐주실 수 있나요??
1
114
1
7강에 대해서 궁금증이 있는데요
1
116
2
Spring MVC에서 corountine 활용 방안
1
538
1
9강 코루틴 중단과 재개관련 문의 드립니다.
0
124
2
suspend 함수에 관해 추가적인 질문 있습니다! (runcatching, Result)
0
126
1
간단 질문.. join() vs delay()
0
157
2
코루틴을 잘 사용하고 있는지 궁금합니다.
0
196
1
CoroutineScope & Dispatcher 질문
0
160
2
async await 관련 질문
1
135
2
코루틴 실행 순서 궁금합니다.
1
231
2
corutine task에 대한 질문
1
195
2
completing의 존재의의가 궁금합니다.
1
161
1
코루틴 dispatcher IO관련 질문
0
187
1
Job 질문이 있습니다
1
203
1
스프링 MVC 환경에서의 코루틴
1
2093
1
한 suspend fun 의 반환값이 다른 suspend fun의 파라미터로 쓰일 때
1
329
2
delay 함수에 대해 질문이 있습니다
1
392
1
runBlocking을 사용하는 경우가 있을까요?
0
399
1
delay가 없으면 실행 안 되는 이유
0
294
1
코루틴 스코프
0
312
1
CoroutineScope 와 withContext 의 차이를 잘 모르겠습니다.
1
699
1





