我公开无状态EJB作为REST服务。在我的POST方法,我称之为Java:取消REST服务方法执行
Result r = longRunningBusinessMethod();
//return data
如何去使其能够取消longRunningBusinessMethod()从客户端执行? 我想过为该方法创建一个线程,并将所有正在执行的线程与一个ID一起保存在散列表中,以便用户可以发布其ID以终止该线程。但我相信必须有更好的解决方案。 任何帮助将不胜感激。
我公开无状态EJB作为REST服务。在我的POST方法,我称之为Java:取消REST服务方法执行
Result r = longRunningBusinessMethod();
//return data
如何去使其能够取消longRunningBusinessMethod()从客户端执行? 我想过为该方法创建一个线程,并将所有正在执行的线程与一个ID一起保存在散列表中,以便用户可以发布其ID以终止该线程。但我相信必须有更好的解决方案。 任何帮助将不胜感激。
我认为“保留ID表”的粗略设计是一个很好的起点。我可能会使用带有线程池的ExecutorService,然后保留Map<ID, Future>
,以便取消未来。 (同时确保每个将来从地图上删除自身,因为它成功完成或异常。)
您还可以实现longRunningBusinessMethod
,使其包含足够的地方,它检查看它是否被中断 - 取消未来只会在线程上设置中断标志,它实际上并不会停止执行代码。如果您的长时间运行方法已经丢弃InterruptedException
,那就好了。否则,您需要添加一些虚拟电话,如Thread.sleep(1)
,或者每隔一段时间手动检查Thread.interrupted()
,然后自己抛出InterruptedException
。
中断工作线程总是很棘手,一般不推荐。一种解决方法是修改正在运行的业务方法,询问是否应完成其执行。例如:
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或缓存它是否应该被中断。然后,通过REST API很容易在DB或高速缓存中为此特定作业更改'shouldInterrup'值。
这就是我将如何做到这一点。而我不知道我必须手动终止我的线程。简短和相关的问题:当我使用'Future#get(30,TimeUnit.Seconds)'时,底层方法在超时异常被抛出后仍然会执行吗? – User9123
当超时异常被抛出时,底层方法_may_仍然在执行。这只会在正在执行'longRunningBusinessMethod'的线程上设置'interrupt'标志,因此代码仍然需要以可中断的方式编写。 –