runBlocking 코루틴, job1 코루틴, job2 코루틴runBlocking으로 만들어진 코루틴이다.fun main(): Unit = runBlocking {
val job1 = launch {
delay(1_000L)
printWithThread("Job 1")
}
val job2 = launch {
delay(1_000L)
printWithThread("Job 2")
} }
CorutineScope를 사용하면 된다.fun main(): Unit = runBlocking {
val job1 = CoroutineScope(Dispatchers.Default).launch {
delay(1_000L)
printWithThread("Job 1")
}
val job2 = CoroutineScope(Dispatchers.Default).launch {
delay(1_000L)
printWithThread("Job 2")
}
}
Dispatchers.Default로 새로운 스레드에서 코루틴을 실행 시키며 각각의 launch가 루트 코루틴이 되었다.launch 함수는 예외가 발생하자마자 해당 예외를 출력하고 코루틴이 종료된다.fun main(): Unit = runBlocking {
val job1 = CoroutineScope(Dispatchers.Default).launch {
throw IllegalArgumentException()
}
delay(1_000L)
}
// 출력 결과
// Exception in thread "DefaultDispatcher-worker-1 @coroutine#2" java.lang.IllegalArgumentException
async 함수는 예외가 발생해도 예외를 출력하지 않는다.
await 함수를 써야 한다.async는 값을 반환할 수 있기에 값을 반환할 때 예외를 처리하도록 한 것이다.fun main(): Unit = runBlocking {
val job = CoroutineScope(Dispatchers.Default).async {
throw IllegalArgumentException()
}
delay(1_000L)
// job.await() 호출했다면 이 시점에 예외 출력
}
// 출력 결과
//
CorutineScope로 생성한 루트 코루틴이 아닌 자식 코루틴이 되면 async를 사용해도 예외가 바로 출력된다.
runBlocking에 예외가 전파되어 코루틴을 종료하게 되고 runBlocking의 경우 예외를 만나면 바로 출력하게 된다.fun main(): Unit = runBlocking {
val job = async {
throw IllegalArgumentException()
}
delay(1_000L)
}
// 출력 결과
// Exception in thread "main" java.lang.IllegalArgumentException
SupervisorJob()을 사용하면 된다.
async의 원래 행동 패턴대로 동작한다.fun main(): Unit = runBlocking {
val job = async(SupervisorJob()) {
throw IllegalArgumentException()
}
delay(1_000L)
}
// 출력 결과 (예외를 출력하지 않음)
//
fun main(): Unit = runBlocking {
val job = launch() { // async도 동일
try {
throw IllegalArgumentException()
} catch (e: IllegalArgumentException) {
printWithThread("정상 종료")
}
}
}
// 출력 결과
// [main @coroutine#2] 정상 종료
try-catch로 예외를 잡으면 코루틴이 종료되지 않게 할 수 있고 적절한 처리도 할 수 있다.CoroutineExceptionHandler를 사용하면 코루틴 구성 요소와 발생한 예외를 파라미터로 받을 수 있다.
fun main(): Unit = runBlocking {
val exceptionHandler = CoroutineExceptionHandler { _, _ ->
printWithThread("예외 발생")
}
val job = CoroutineScope(Dispatchers.Default).launch(exceptionHandler) {
throw IllegalArgumentException()
}
delay(1_000L)
}
// 출력 결과
// [DefaultDispatcher-worker-1 @coroutine#2] 예외 발생
CoroutineExceptionHandler 주의할 점
launch에만 적용 가능하다.CancellationException이 발생하는 것이었다.CancellationException이 발생한 경우 취소로 간주하고 부모 코루틴에게 전파하지 않는다.CancellationException인지 아닌지에 상관없이 CANCELLING 상태가 된다.ACTIVE 상태에서 성공하면 COMPLETING 상태로 넘어간다.