gpt4 book ai didi

java - 执行端点调用时关闭线程消失

转载 作者:行者123 更新时间:2023-11-30 02:26:28 24 4
gpt4 key购买 nike

我有一个在 Ubuntu 16.04 LTS 上运行的 Java 应用程序。

当应用程序收到关闭信号时,关闭序列将按如下方式运行:

    Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
shutdown();
}
});

这工作正常,但是一旦我尝试调用外部 REST 端点(我将 Retrofit 与 Rx Observables 一起使用),线程就会在那里消失,端点永远不会被调用,连续的命令也不会再执行。

  • 我首先认为 Observables 会是问题所在,并使用了 Retrofit Call反而。同样的问题。
  • 然后我尝试进行同步调用,而不是异步调用端点。同样的问题。
  • 关闭时间不是问题。我明确给出了 30 秒。

我认为这与线程有关,例如当库在关闭时创建额外的线程时,JVM 似乎会杀死所有内容。

任何人都可以阐明或建议我还可以尝试什么吗?

--

额外信息:

我需要执行长时间运行的清理。问题是我无法确定关闭信号是什么样子以及何时发生,因为 JVM 在 Docker 容器中运行,在 docker stop 上(当主机停止时),首先发送SIGTERM ,然后,超时后(我可以设置,当前为 60 秒)SIGKILL 。容器中的 JVM 运行 socket.io,其中可能连接数千个客户端。我想用这60秒发送一个good-bye到每个客户端并彻底断开它们的连接,以及从负载均衡器中取消注册服务器。因此在清理过程中存在很多潜在的阻塞操作。

如果 Java 认为清理总是很短,那么 Java 就错了:(

最佳答案

在您的情况下关闭 JVM 时会引发中断标志。因此,一旦您调用任何阻塞操作,该操作就会立即被 InterruptedException 终止。

如果您必须在应用程序终止时执行进一步的、可能持久的代码,那么关闭 Hook 不是最佳选择。该资源的存在是为了关闭开放资源,而不是创建新资源。

由于您没有提供有关代码的进一步信息,我无法给出确切的建议,但总体思路是让主线程在应用程序运行时等待,并让主线程执行清理工作。然而,在这种情况下,您需要一个不是系统关闭信号的关闭信号,以便应用程序可以继续正常运行。

如果由于某种原因过于复杂,您可以尝试通过执行以下操作来清除关闭 Hook 开头的中断标志:

try {
Thread.sleep(1);
} catch (InterruptedException e) {
}

然而,这违反了规则,而这些规则的存在是有原因的。 IE。如果您的程序没有足够快地对终止信号使用react并以更糟糕的方式终止它,操作系统可能会认为您的程序已挂起。

关于java - 执行端点调用时关闭线程消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45557857/

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