【发布时间】:2016-01-08 09:12:30
【问题描述】:
我最近使用 GlassFish / Payara 构建了一个 Java EE 7 Web 应用程序。 Web 应用程序在底层操作系统上按需启动长时间运行的任务(> 2 小时)。这些任务基本上是用 Python、Ruby 或 Java 编写并使用命令行 (Apache Commons Exec) 执行的其他程序或脚本。由于我想通知用户任务的当前状态并让他可以取消正在运行的任务,因此我使用了以下 Java EE 功能和库。
以下列表简要描述了我决定使用特定 Java EE 功能或外部库的原因。
-
ManagedExecutorService
- 使用 @Resource 注入,允许我将 Runnables 排队并在自己的线程中执行它们
-
ManagedTaskListener 实现
- 这就是我实际上决定使用 ManagedExecutorService 并在应用程序服务器中运行线程的原因
- 界面为我提供了四个非常方便的方法(taskSubmitted、taskAborted、taskDone 和 taskStarting)
- 这让我可以更新长期运行任务状态 (JPA) 并在状态发生变化时通知用户
-
可运行的托管任务实施
- 这里我通过重写 run() 方法定义了实际长时间运行的任务
- 为了对状态变化做出反应,我还注册了 ManagedTaskListener 实现,如前所述
-
Apache Commons Exec Util
- 要实际执行长时间运行的任务,Runnable 和 ManagedTask 实现只需使用 apache commons exec
- 为了能够取消长时间运行的进程,我为每个 DefaultExecutor 设置了一个 ShutdownHookProcessDestroyer
- 使用 defaultExecutor.getWatchdog().destroyProcess();这让我可以杀死正在运行的任务
我知道将 ManagedExecutorService 与 ManagedTasks 结合使用来执行如此长时间运行的任务并不是最好的主意,但它工作得相当稳定。
但是知道我想在不同的物理机器上运行这些长时间运行的任务并仅使用 Java SE 执行它们。这意味着我没有 ManagedExecutorService,因此没有 ManagedTaskListener 接口。
有没有人遇到过这种情况?也许有提供类似功能的库。我认为 Google Guava 提供了一些类似方向但没有提供相同功能的东西。
我也感谢其他解决方案。
非常感谢!
【问题讨论】:
-
“要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。”
标签: java multithreading guava java-ee-7 apache-commons-exec