gpt4 book ai didi

java - 在 JVM 关闭时触发 AutoClosable

转载 作者:行者123 更新时间:2023-12-03 12:47:00 24 4
gpt4 key购买 nike

长话短说:有没有办法发现,JVM 关闭仅在我的代码启动的线程中被阻止?例如,是否可以在关机时自动触发 AutoCloseable.close()?

上下文

我正在构建一个库,应该供多个客户使用。这意味着,除了提供文档外,我无法强制执行某些事情。

架构

(我尽量描述的比较抽象,避免不必要的细节)

我有一个“Manager”对象(类似于工厂),用于创建“Service”对象,而“Service”对象又需要一些数据才能相应地工作。由于该数据是从某些“慢速”后端服务(也可能不时更改)加载的,因此我使用了一个单独的(守护进程)线程来检查更新并尽快将新数据注入(inject)该服务。 (这也意味着除非第一次更新,否则该服务只是处于“noop 模式”。但这没关系。)

现在,“更新程序”(在我的守护线程中运行)使用一个库,该库在打开连接时再次启动一个线程,并且有必要调用“关闭”以确保该辅助线程停止 - 否则不可能, 以正确关闭 JVM。

作为安全网,我在“管理器”的 finalize() 方法中调用了 close() 方法(它保持对所有 Updater 实例的引用)。这不是 100% 安全的,因为它无法预测 GC 何时运行(甚至在关闭期间更是如此!),但这是我唯一的选择。

更新:Here is some abstract example code that illustrates the architecture and the according problem

问题

这种架构会导致两个可能的陷阱:

  1. 如果实现不保留对管理器实例的引用,它将在某个时候被垃圾收集,并通过 finalize 方法停止必要的后台更新。

  2. 如果实现保留管理器的实例,则必须在相应系统关闭期间调用 close 方法,否则 JVM 无法正常终止。

所以我的实际问题是使用该库的开发人员的“潜在不可靠性”。

有没有人知道如何构建可以解决这两个陷阱的解决方案?如果有一些在关闭期间调用的 Auto-AutoCloseable ;) 会很好(例如,通过 DestroyJavaVM 线程或类似的)。

我尝试失败的解决方案

  1. 在 Updater 中,我正在关闭“try-finally” block 中的“有问题的”连接,但该守护线程也不会自动中断/停止。

  2. 我注册了一个 Runtime.getRuntime().addShutdownHook(...) 它将关闭所有连接,但是这个关闭 Hook 从未被调用,因为关闭仅在所有用户启动时启动-线程已停止。

更新:在我的实现中解决了,但不是问题

我解决了我的问题,因为我发现第三方库(RabbitMQ 客户端)提供了一个 setThreadFactory 方法,我可以使用它来确保生成的线程是守护进程线程。祝我的第 3 方库好运,但所描述的问题仍然存在。

最佳答案

我想您希望关闭 AutoCloseable 资源以便有序关闭。

AutoCloseable 对象应该(由您的图书馆客户)以确保在不再需要时关闭它们的方式使用。在几乎所有情况下,它们都应该使用 try-with-resources block ,因此即使抛出异常它们也会关闭。

您应该利用这一点,要求您的库客户端在收到关闭程序的请求时对每个线程执行受控关闭。线程通过从每个 Runnable.run 方法返回或从每个 Runnable.run 方法抛出异常来执行受控关闭。我相信这是关闭资源的唯一可靠方法,因为它确保嵌套资源分配以正确的顺序重新分配。更一般地说,作为图书馆编写者,您无法知道您的图书馆客户可能希望在关闭时执行哪些其他操作,因此您应该让他们完全控制关闭。

您可以通过让您的库代码正确处理 InterruptedException 和 Thread.interrupted 标志来帮助他们做到这一点。

关于java - 在 JVM 关闭时触发 AutoClosable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47269705/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com