本篇解析 example-cancel-09.kt,探讨超时与资源管理之间的一个隐蔽 Bug。
1. 核心场景
在一个循环中启动大量协程,每个协程都会:
withTimeout(60):设置 60ms 超时。delay(50):模拟耗时操作。Resource():分配资源。resource.close():释放资源。
2. 核心问题:资源泄漏
你会发现程序运行完后,acquired 变量的值并不为 0。
- 原因:由于超时是异步且并发发生的。可能在
Resource()构造函数刚刚执行完,资源已经分配(acquired++),但还没来得及赋值给变量或执行下一步时,超时信号传来了。 - 后果:协程被取消并抛出异常,
resource.close()永远没机会被执行。
3. 开发者感悟
这是一个非常经典的并发竞争问题。它提醒我们:分配资源的操作与释放资源的操作之间,如果存在被异步取消的可能性,就必须采取更严密的保护措施。