如何强制Java REST应用程序进入空闲状态?

时间:2018-05-31 03:48:25

标签: java multithreading

我有一个包含大约30个端点的REST应用程序。除此之外,用户还可以提交需要处理20-60分钟的后台任务。有时很明显,提交的请求永远不会从日志中完成,但是,我唯一能做的就是重新部署相同版本的代码。

我希望能够通过

杀死类似于mySQL的过程
%APPDATA%/Python/PythonXY/site-packages

我试图用Thread.currentThread()。interrupt()来实现,但那并没有真正做任何事情。我在整个应用程序中多次使用CompletionService和多线程来加速进程。

我的目标是,我应该能够调用此API将应用程序返回到没有进程正在运行时所处的状态。我检查了这篇文章,但似乎每个人都在警告它。

How to find and stop all currently running threads?

可以这样做吗?

1 个答案:

答案 0 :(得分:2)

为什么Thread.currentThread()。interrupt()没有工作

Thread.currentThread()返回您正在运行的当前线程的Thread对象,因此如果您在后台任务线程之外调用它,它将不会返回对后台线程的引用。如果你想要引用你的后台线程,你必须自己跟踪它。

thread.interrupt()在您的线程上设置中断标志。但是如果你的线程从未明确地检查中断标志,它就不会做任何事情。您必须定期检查后台任务中的中断标志,然后采取适当的措施。

if (Thread.currentThread().isInterrupted()) {
  finishWork(); // Close any resources used.
  return;
}

对于您的用例,我实际上不鼓励在后台任务中使用interrupt(),尤其是在使用Threadpool时。特别是如果您使用的是Threadpool,则可以重用相同的线程来运行多个后台任务。由于线程被重用,因此可能会意外中断您从未打算过的后台任务。

如何停止后台任务

这需要做大量的工作,但这是可行的。下面我将介绍一个非常基本的实现,它对您的用例就足够了。

  1. 首先,您必须创建类似SpringBoot服务的东西。这是一个单例类,它被注入到执行其余端点的所有类中。该服务将是一个后台任务跟踪器,它保留从任务ID到标志的映射,指示是否应该终止该任务。
  2. 接下来,您必须创建一个休止端点来终止后台任务。其余端点应将任务ID作为查询参数或路径参数终止。
  3. 当端点执行时,您可以在后台任务跟踪器上调用terminate方法,该方法将翻转指示应终止任务的标志。 注意:您的后台任务可能在您实际终止之前已经完成,因此您的代码应处理此极端情况。
  4. 启动后台任务时,应该为后台任务跟踪器提供参考。
  5. 后台任务应该做的第一件事就是创建一个唯一的任务ID。您可以先使用UUID.randomUUID()
  6. 开始
  7. 创建任务ID后,将其提供给后台任务跟踪器。
  8. 在后台任务的日志中打印任务ID。
  9. 后台任务可以继续执行其工作,但如果已取消后台任务跟踪器,则应定期检查后台任务跟踪器。如果没有继续处理,如果是,则关闭所有使用的资源并返回。
  10. 在退出后台任务之前,应将其从后台任务跟踪器中删除,以避免内存泄漏。
  11. 重要说明

    在实现之前,请务必阅读如何正确同步java中线程之间的通信。这是一个很好的资源https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html