java - 如何维护一个持久化的后台线程?

标签 java multithreading

总结

我有一个应该长时间运行的服务器,它会为 IO 生成一些后台线程。我试图确保后台/IO 线程不会关闭,或者如果它们关闭,它们将被恢复。

当前解决方案

目前我的主循环只检查所有背景检查的状态(下面的伪代码)。我认为应该有更好的方法。

while (!Thread.currentThread().isInterrupted()) {
    maintainThreads();
    doWork();
    condition.await(30, TimeUnit.SECONDS);
}

我的尝试

我正在考虑切换到 SingleThreadExecutor,它有一个自定义的 queue,当它拉下一个任务时不会删除 Runnable . executor 然后会为我管理线程,这样我就可以将它从我的主循环中取出。

我担心为每个线程配备一个执行程序会影响性能,并且存在针对此问题的更简单/更好的解决方案。我还考虑过为每个线程设置关闭 Hook ,让它们自行重启。

如有任何帮助,我们将不胜感激。

最佳答案

这里真正的陷阱是您在“或者如果它们确实下降时将被恢复”中的下降的意思。

据我所知,只有两种方法可以使线程关闭,而整个进程本身不会在 java 中退出:

  1. run() 方法通过异常或正常(即非异常)完成运行方法终止。
  2. Thread.stop() 在您的线程上被调用。

让我们先解决 (2) - Thread.stop() 已被弃用,并且在任何运行良好的应用程序中都是一个大禁忌。你几乎可以假设它不会被调用,因为如果它被调用,你的 application is already badly broken .此时重新启动任何线程可能会产生未定义的效果,因为您的应用程序处于不一致状态。

那么对于 (1),您只需确保 run() 不会终止。它不会正常终止,因为您已经设置了一个无限循环。要阻止它异常终止,您可以catch (Throwable t) 并继续循环(在正确记录错误后)。

当然,没有后续重新抛出的 catch (Throwable t) 通常是一种代码味道。这意味着您遇到了一些未指定的错误,然后决定继续前进。错误的范围可能从良性(例如,SockedClosedExcpetion,因为远程客户端断开连接)到不可恢复的(例如,OutOfMemoryError 或更糟的错误)。您真的应该问问自己,如果遇到任何 类型的异常,您是否希望此线程继续。

您的申请可能处于无效状态,可能无法继续。一种妥协是只捕获 Exception 的子类并在出现 Error 时终止应用程序。一种更保守的方法是在您不知道如何处理的任何类型的异常上终止应用程序(并将其视为要修复的错误)。

关于java - 如何维护一个持久化的后台线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41336881/

相关文章:

java - 如何在 hibernate 条件中使用日期部分

java - 在线程java中计算pi

Android:在用户界面中显示的计时器

multithreading - 从新线程中处理 ExcelDnaUtil.Application

java - 模型映射器 - 使用自定义方法

java - 在 SymmetricDS Embedded 中创建 SYM 表

java - 从一个 ArrayList 转移到另一个

Java 比较泛型和 Void

java - 为什么需要以毫秒为单位的超时以及为什么我必须为单独的 block 声明两个具有单独 run () 方法的类

java - ExecutorService 添加延迟