You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin未处理协程异常未触发程序崩溃的原因探究

为什么协程抛出异常后程序没有崩溃?

嘿,这个问题问到点子上了!咱们来一步步搞清楚背后的原因:

首先得明确:Kotlin协程的异常传播逻辑和普通线程完全不同,这也是你预期和实际结果不符的核心所在。

核心原因:协程的异常处理机制

当你通过CoroutineScope(比如代码里的scope = CoroutineScope(Dispatchers.Default))启动launch协程时,协程抛出的未捕获异常会被协程框架的默认异常处理器接管:

  • 在JVM平台上,这个默认处理器只会打印异常的堆栈信息,并不会触发整个进程的崩溃。
  • 对比普通线程:如果普通线程抛出未捕获异常,JVM会直接终止整个进程,这也是你一开始以为程序会崩溃的原因。

再看你的代码细节

  1. 你创建的协程是依附于自定义CoroutineScope的顶级协程,它的异常不会直接"逃逸"到承载它的线程上导致进程终止。
  2. 主线程在启动协程后,执行了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:22:46