[英]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 引用有点费力,你必须维护自己的引用列表和事后处理线程。 另一方面,您完全可以控制。
本文解释并比较了 Java finalize()
和Phantom 引用的实现。
您可以将线程作为关闭挂钩添加到运行时:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// cleanup code
}));
这在 VM 终止时被调用,因此在您的特定情况下它应该是finalize
一个很好的替代品
恕我直言,告诉记录器清理自己的烂摊子不是您的应用程序的责任。 记录器本身可以而且应该这样做(与 IO 流或数据库连接不同),它应该存在很长时间。
但是您已经提供了logger.close()
... 好的,那么我建议如下:
close
是幂等的,即第二次关闭记录器是无操作的。Runtime#addShutdownHook
和PhantomReference
,并让它们都调用logger.close()
,以便在 JVM 终止或您的应用程序被logger.close()
同时调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.