Java SE的ManagedExecutorService,ManagedTask和ManagedTaskListener替代

时间:2016-01-08 09:12:31

标签: java multithreading guava java-ee-7 apache-commons-exec

我最近使用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)并通知用户是否发生状态更改
  • Runnable,ManagedTask Implementation
    • 这里我通过覆盖run()方法
    • 来定义实际的长时间运行任务
    • 为了对状态更改做出反应,我还注册了ManagedTaskListener实现,如前所述
  • Apache Commons Exec Util
    • 要实际执行长时间运行的任务,Runnable和ManagedTask实现只使用apache commons exec
    • 为了能够取消长时间运行的进程,我按DefaultExecutor设置了ShutdownHookProcessDestroyer
    • 使用defaultExecutor.getWatchdog()。destroyProcess();这允许我杀死一个正在运行的任务

我知道将ManagedExecutorService与ManagedTasks结合使用以执行如此长时间运行的任务并不是最好的主意,但它的工作非常稳定。

但是我知道我想在不同的物理机器上运行这些长时间运行的任务,并仅使用Java SE执行它们。这意味着我没有ManagedExecutorService,因此没有ManagedTaskListener接口。

有没有人有这种情况的经验?也许有库提供类似的功能。我认为谷歌番石榴提供了类似的方向,但没有提供相同的功能。

我也很感谢其他解决方案。

非常感谢!

1 个答案:

答案 0 :(得分:0)

使用Java SE执行程序(即ScheduledExecutorService)提交进行必要更新的Runnable / Callable。

您必须实现自己的等效ManagedTask / ManagedTaskListener,但这应该可以通过Runnable / Callable实现轻松实现。

旁注:
当您使用ManagedTask时,这是在ManagedTask上设置ManagedTask.LONGRUNNING_HINT=true的完美方案。例如:

managedTask.getExecutionProperties().put(ManagedTask.LONGRUNNING_HINT, "true");