本文介绍如何在使用 executorservice 提交异步任务获取 closeable 资源时,安全实现带超时的 `future.get()`,并在超时后自动释放未完成任务中已创建但未返回的资源,避免资源泄漏。
在 Java 并发编程中,Future.get(timeout, unit) 是控制异步任务执行时间的常用手段。但当任务返回一个需显式关闭的资源(如 InputStream、数据库连接、网络 socket 等)时,若主线程因超时而放弃等待,该资源可能已在后台线程中成功创建却无人持有引用,更无法被关闭——这将导致严重的资源泄漏。
根本问题在于:Future 本身不提供“任务取消时回调”或“结果就绪但被丢弃时清理”的机制。标准 Future.cancel(true) 可中断线程,但无法保证资源已构造完成且可安全关闭;而若任务已进入 getCloseableResource() 内部并成功分配了资源,中断可能发生在 close() 之前,造成泄漏。
✅ 正确解法:将资源生命周期与任务状态解耦,并引入线程安全的“废弃标记”(abandon flag),由后台任务自行判断是否需主动清理。
以下是一个生产就绪的实现方案:
立即学习“Java免费学习笔记(深入)”;