MST
星途 面试题库

面试题:Kotlin协程的异常处理机制及在不同场景下的应用

描述Kotlin协程中未捕获异常的默认处理机制。并举例说明,在父子协程、并发协程等不同场景下,如何正确地处理异常以确保程序的稳定性和健壮性。
43.5万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

Kotlin协程中未捕获异常的默认处理机制

在Kotlin协程中,未捕获的异常默认会导致协程取消,并向上传播给父协程。如果到达顶层协程仍未处理,该异常会被发送到CoroutineExceptionHandler。若没有为协程作用域设置CoroutineExceptionHandler,则异常会通过Thread.UncaughtExceptionHandler处理,默认情况下会使当前线程终止(如果协程在主线程中运行,这将导致应用崩溃)。

父子协程场景下处理异常

在父子协程中,子协程的异常默认会导致父协程取消。可以通过在父协程作用域设置CoroutineExceptionHandler来捕获子协程的异常。

import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught $exception")
    }
    val parentJob = GlobalScope.launch(handler) {
        launch {
            throw RuntimeException("Child coroutine exception")
        }
    }
    parentJob.join()
}

在此例中,CoroutineExceptionHandler设置在父协程的GlobalScope.launch中,当子协程抛出异常时,CoroutineExceptionHandler会捕获并处理该异常,防止异常向上传播导致程序崩溃。

并发协程场景下处理异常

在并发协程场景下,并发运行的多个协程之间没有父子关系。可以为每个协程单独设置CoroutineExceptionHandler,或者为它们共同的作用域设置CoroutineExceptionHandler

import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught $exception")
    }
    val job1 = GlobalScope.launch(handler) {
        throw RuntimeException("First concurrent coroutine exception")
    }
    val job2 = GlobalScope.launch(handler) {
        delay(100)
        println("Second concurrent coroutine is still running")
    }
    job1.join()
    job2.join()
}

在此例中,为每个并发协程都设置了相同的CoroutineExceptionHandler。当job1抛出异常时,CoroutineExceptionHandler捕获并处理异常,job2不受影响继续运行,确保程序的稳定性和健壮性。