我将无状态EJB公开为REST服务。在我的POST方法中,我打电话给
Result r = longRunningBusinessMethod();
//return data
如何从客户端取消 longRunningBusinessMethod()的执行? 我考虑为该方法创建一个线程,并将所有正在执行的线程与一个id一起保留在哈希表中,以便用户可以POST他的id来终止该线程。但我相信必须有更好的解决方案。 任何帮助将不胜感激。
答案 0 :(得分:2)
中断工作线程总是很棘手,一般不推荐。一种方法是修改正在运行的业务方法,询问是否应该完成执行。例如:
public void longRunningBusinessMethod(JobContext context){
while(someCondition) {
if(shouldInterrupt(context)){
log.info("Interrupting longRunningBusinessMethod");
...
<close all the resources and terminate the job>
}
}
}
shouldInterrupt(context)
将获取带有作业ID的作业上下文,并询问DB或Cache是否应该被中断。然后,可以通过REST API轻松更改此特定作业的DB或Cache中的“shouldInterrup”值。
答案 1 :(得分:1)
我认为“保持身份证表”的粗略设计是一个很好的起点。我可能不会在外部终止线程,而是使用带有线程池的ExecutorService,然后保留Map<ID, Future>
,这样就可以取消将来。 (还要确保每个未来都会从地图中删除,因为它会成功地或成功完成。)
你还必须实现longRunningBusinessMethod
,以便它包含足够的位置来检查它是否被中断 - 取消未来只会在线程上设置中断标志,它实际上并不停止来自执行的代码。如果您的长时间运行方法已经抛出InterruptedException
,那么就可以了。否则,您需要添加一些虚拟调用,例如Thread.sleep(1)
,或者经常手动检查Thread.interrupted()
,然后自己抛出InterruptedException
。