资源生命周期与 AutoCloseable

资源所有权与 AutoCloseable:谁创建谁关闭、跨层传递资源时的生命周期纪律。

#type / concept #status / growing #tech / dev #resource / java

[!info] 关联笔记

资源生命周期与 AutoCloseable

这个概念为什么出现

资源泄漏是生产慢性病:连接耗尽、文件句柄打满。技术机制是 close,工程机制是所有权:谁创建,谁负责释放;谁借用,谁按契约归还。

[!abstract] 一句话理解 AutoCloseable 标出可关闭资源;生命周期纪律是“所有权清晰 + 异常路径也释放 + 池化资源按池契约归还”。

最小可运行示例

场景:包装一个计数型资源,确保 close 只成功一次

import java.util.concurrent.atomic.AtomicInteger;

final class Lease implements AutoCloseable {
    private static final AtomicInteger OPEN = new AtomicInteger();
    private boolean closed;
    Lease() { OPEN.incrementAndGet(); }
    static int openCount() { return OPEN.get(); }
    @Override public void close() {
        if (!closed) {
            closed = true;
            OPEN.decrementAndGet();
        }
    }
}

public class LeaseDemo {
    static void use() {
        try (Lease lease = new Lease()) {
            System.out.println("in-use=" + Lease.openCount());
        }
    }
    public static void main(String[] args) {
        use();
        System.out.println("after=" + Lease.openCount());
    }
}

建议运行:

javac LeaseDemo.java && java LeaseDemo

期望输出:

in-use=1
after=0

结合场景再看三个关注点

  1. close 应幂等(多次关闭安全)。
  2. 作用域结束即释放,不要把短生命周期资源塞进长期字段。
  3. 池化对象的 close 可能是归还,不是物理销毁——读文档。

核心概念与准确模型

1. 所有权转移

模式责任
工厂返回资源文档写清由调用方关闭
方法内打开方法内 TWR 关闭
依赖注入单例客户端应用停止时关闭

2. Closeable vs AutoCloseable

  • Closeable 继承 AutoCloseablecloseIOException
  • 更广资源实现 AutoCloseable

3. 与优雅关闭关系

进程退出前要关闭线程池、服务端 socket、数据源——见服务工程。

边界情况与反直觉行为

  1. 关闭顺序:先依赖方后底层。
  2. 异步回调持有资源易泄漏。
  3. 异常构造半对象时注意已获取资源回滚。

常见误区

[!warning] 常见误区:连接池拿来的 Connection 不关闭 必须 close/归还,否则池耗尽。

工程实践

  1. API 文档写清 ownership。
  2. 静态分析/实验检测泄漏。
  3. 超时与取消路径也要释放。
  4. 测试用计数/代理断言 close 次数。

本节总结

  • 资源=所有权问题
  • AutoCloseable + TWR 是机制
  • 池化与进程级关闭是工程延伸

自测题

  1. 为什么 close 最好幂等?
  2. 方法返回 InputStream 时谁关闭?
参考答案
  1. 防御双重关闭与错误路径重复清理。
  2. 通常调用方;文档必须明确,否则必泄漏。

延伸阅读与资料来源

资料类型支撑内容
AutoCloseableAPI契约
CloseableAPIIO 关闭
创建于 2026/7/15 更新于 2026/7/15