Kotlin未处理协程异常未触发程序崩溃的原因探究
为什么协程抛出异常后程序没有崩溃?
嘿,这个问题问到点子上了!咱们来一步步搞清楚背后的原因:
首先得明确:Kotlin协程的异常传播逻辑和普通线程完全不同,这也是你预期和实际结果不符的核心所在。
核心原因:协程的异常处理机制
当你通过CoroutineScope(比如代码里的scope = CoroutineScope(Dispatchers.Default))启动launch协程时,协程抛出的未捕获异常会被协程框架的默认异常处理器接管:
- 在JVM平台上,这个默认处理器只会打印异常的堆栈信息,并不会触发整个进程的崩溃。
- 对比普通线程:如果普通线程抛出未捕获异常,JVM会直接终止整个进程,这也是你一开始以为程序会崩溃的原因。
再看你的代码细节
- 你创建的协程是依附于自定义
CoroutineScope的顶级协程,它的异常不会直接"逃逸"到承载它的线程上导致进程终止。 - 主线程在启动协程后,执行了
Thread.sleep(1000),这段时间里协程抛出异常、被默认处理器处理并打印日志,之后主线程继续执行到println("exit without crash"),最后正常退出进程。
想让程序崩溃?试试这些方式
如果希望协程异常导致进程崩溃,可以做以下调整:
- 自定义
CoroutineExceptionHandler,在处理器中主动终止进程:
val handler = CoroutineExceptionHandler { _, exception -> println("Caught $exception") Runtime.getRuntime().exit(1) } val scope = CoroutineScope(Dispatchers.Default + handler)
- 改用
runBlocking作用域:runBlocking会将协程内的未捕获异常重新抛到调用它的主线程,从而触发进程崩溃:
import kotlinx.coroutines.* fun main() = runBlocking { launch { delay(100) throw RuntimeException("1") } println("sleep") delay(1000) println("exit without crash") }
- 使用
async并调用await:async的异常会在调用await时抛出,若未捕获则会导致进程崩溃。
内容的提问来源于stack exchange,提问作者Nubcase
相关产品推荐
相关产品推荐

