繁体   English   中英

在 Java 中替换 finalize()

[英]Replacing finalize() in Java

Object.finalize()在 Java 9 中已被弃用,我想我明白原因,但我无法看到如何替换它。

我有一个名为 Configuration 的实用程序类,它本质上有一个实例,该实例拥有应用程序中的所有内容,并在应用程序的整个过程中持续存在。 它提供的服务之一是日志记录:在第一次请求记录消息时,会创建一个记录器(出于各种遗留原因,它是我自己的记录器而不是标准记录器),并在 Configuration 对象的字段中保存一个引用,并且在应用程序终止时,无论是正常还是异常,我想释放记录器持有的任何资源(这是一个黑匣子,因为我的库的用户可以提供他们自己的实现)。

目前这是通过调用logger.close()Configuration.finalize()方法实现的。

我应该怎么做?

Java 9 引入了Cleaner和 Cleanable 实用程序类,它们负责将幻像引用连接到队列和清除该队列的清理线程。

虽然这可以让您分离出将在拥有对象死亡后执行事后清理的见证人,但关于 GC 触发的资源管理的所有警告仍然适用,即仍然最好依赖AutoClosable和 try-with-resources块来管理资源的生命周期,而不是垃圾收集器。

幻像引用finalize()一般替代。 Java 运行时的许多类已经在使用它们。

使用Phantom 引用有点费力,你必须维护自己的引用列表和事后处理线程。 另一方面,您完全可以控制。

这是Phantom 参考设置的简单示例

本文解释并比较了 Java finalize()Phantom 引用的实现

您可以将线程作为关闭挂钩添加到运行时:

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    // cleanup code
}));

这在 VM 终止时被调用,因此在您的特定情况下它应该是finalize一个很好的替代品

恕我直言,告诉记录器清理自己的烂摊子不是您的应用程序的责任。 记录器本身可以而且应该这样做(与 IO 流或数据库连接不同),它应该存在很长时间。

但是您已经提供了logger.close() ... 好的,那么我建议如下:

  • 确保close是幂等的,即第二次关闭记录器是无操作的。
  • 使用Runtime#addShutdownHookPhantomReference ,并让它们都调用logger.close() ,以便在 JVM 终止或您的应用程序被logger.close()同时调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM