协程进阶:10. 安全的资源清理实践

本篇解析 example-cancel-10.kt,给出解决超时下资源泄漏的终极方案。

1. 核心改进

对比示例 09,本例通过标准的 try-finally 结构重构了逻辑。

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
launch {
var resource: Resource? = null // 1. 先在外部声明变量
try {
withTimeout(60) {
delay(50)
resource = Resource() // 2. 在超时块内分配资源并赋值
}
} finally {
// 3. 无论超时是否发生,只要变量不为空,就执行清理
resource?.close()
}
}

2. 为什么这样安全?

  • 原子性保障:即使 withTimeout 抛出了异常,执行流也会跳转到 finally
  • 清理可靠:在 finally 中检查 resource。如果资源已经成功创建,它一定会被关闭。
  • 结果:无论运行多少次,acquired 变量的值最终一定为 0。

3. 开发者感悟

在处理诸如数据库连接、Socket、文件句柄等重要资源时,永远不要假设代码会按部就班地执行完。异步环境(如协程取消、超时、异常)无处不在。使用 try-finally 是每一位合格协程开发者的基本功。

,