java在返回可能的alreadyset实例时,DeferredResult是否有竞争条件?
我在SpringMVC应用程序中使用DeferredResult来处理可能长期运行的操作的一些服务器端处理。它可能非常快,也可能需要一两秒钟
但是在任何一种情况下,传入的HTTP请求都会导致一个操作被推送到一个队列,由一个独立的线程(通过一个ExecutorService
)负责消费该队列。然后调用回调,通知推送程序操作已完成
我将其中一些行为重构为实用程序方法:
public static DeferredResult<String> toResponse(GameManager gameManager, final Player player, Action action) {
DeferredResult<String> deferredResult = new DeferredResult<>();
gameManager.execute(action, new Handler<Result>() {
@Override
public void handle(Result result) {
JSONObject obj;
try {
obj = gameManager.getGameJSON(player);
obj.put("success", result.getResult());
obj.put("message", result.getMessage());
deferredResult.setResult(obj.toString()); // POINT B
} catch (JSONException e) {
deferredResult.setErrorResult(e);
}
}
});
return deferredResult; // POINT A
}
但是我想知道,如果动作的执行速度如此之快,以至于在返回(POINT A
)给调用方法之前,setResult()
方法在DeferredResult
上被调用(POINT B
),会发生什么
Spring是否会看到返回的DeferredResult
已经有了一个值并处理它,或者它只是在提供了实例之后才开始“监视”setter被调用
# 1 楼答案
我没有使用Spring,但我会说,如果结算时间对下游行为有任何影响,那么
Class DeferredResult<>
将是延迟的一个相当糟糕的实现似乎可以安全地假设,无论异步进程的计时是毫秒、秒还是其他时间,行为都是相同的,唯一的条件是没有发生超时,在这种情况下
onTimeout
处理程序将运行(如果设置)。即使延迟被同步解决,在创建它的同一代码块中,调用方函数也应该按照预期对结果进行操作如果这个假设无效,那么
Class DeferredResult<>
就不适合使用,不应该使用