我有一个java客户端,它在新线程中管理其服务器调用,以防止GUI冻结。
即使在许多地方阻止了这种情况,也可能在同一模型上再次调用该方法,例如使用不同的参数。在这种情况下,我显然希望最新的调用,具有最新的参数,是“成功”并显示其结果。
我有一个跟踪先前启动的Thread的系统,并在启动新的Thread(Thread.interrupt()
)之前中断它。然后,其他方法在将新结果发送到GUI元素之前检查它们是否在非中断线程中运行(使用if (Thread.currentThread().isInterrupted()
)。
这个结构正在使用之前的服务器连接器,因为我是唯一一个检查进程中断标志的人。我的问题是我现在在客户端使用EJB方法调用,并且他们对中断的线程反应很差。在EJB调用期间中断线程将触发RuntimeException
,其中包含InterruptedException
。这似乎不太正常。
显然我可以在每次服务器调用中捕获RuntimeExceptions并检查它们的中断原因,但它看起来不是很“干净”。
我的问题是:在这种情况下我该怎么办?中断运行EJB方法调用的线程的正确方法是什么?
答案 0 :(得分:1)
看到你不介意在服务器上继续使用过时的EJB调用,为什么不允许调用线程“自然地”终止但是丢弃结果因为它的调用已经被另一个线程取代了?我没有时间提供示例实现,但您可能会发现使用Future
和相关的Java并发类获得了一些里程。
修改强>
除此之外,你可能会发现这样的东西可以解决这个问题,但对我来说感觉很烦,我相信还有更优雅的解决方案。
在调用线程上(可能是按钮的onclick方法):
AsynchronousResultManager.registerRequest("UNIQUE_IDENTIFIER", runnableExecuteRequest);
registerRequest
会执行以下操作:
registerClick(String id, Runnable execution) {
AtomicReference ref = executions.get(id); //executions is a Map<String, AtomicReference> created as a a computing map by Guava MapMaker
execution.setReference(ref); //so that the Runnable has a reference to it later
ref.set(execution); //this will overwrite an existing reference to a previous invocation.
//here you need to actually kick off your thread in whatever way works best for you
}
执行请求的runnable
将是以下的子类:
public abstract class RequestRunnable implements Runnable {
private AtomicReference ref;
public void run() {
doRunInternal(); //actually go off and do the request to the J2EE server
if (this == ref.get()) { //ie if the current runnable is the same as in the reference, we can proceed to actually dispatch the result
dispatchResult(); //this method would do something like add a runnable to the SwingWorkerThread
}
}
protected abstract void doRunInternal();
protected abstract void dispatchResult();
public void setReference(AtomicReference ref) {
this.ref = ref;
}
}
这可能会崩溃并烧毁,但希望它能指出你的一条询问线......
答案 1 :(得分:0)
要停止线程,您需要执行两种操作:
在任何情况下,要正确地执行此操作,您需要您希望停止处理这两种情况的线程运行的代码。这里没有银弹。
答案 2 :(得分:0)
鉴于现有架构,我最终以每种服务器调用捕获RuntimeException,其形式为:
try {
return getEJBService().getServiceResult(param, param, param);
} catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof InterruptedException)
throw (InterruptedException)cause;
else
throw e;
}
这不是很漂亮,但至少它允许我根据当前模型的中断行事。
在理想世界中,我们应该选择one of the solutions给出的Rich。