我正在使用DeferredResult在我的 Spring MVC 应用程序中处理一些可能长时间运行的操作的服务器端处理。它可能非常快,或者可能需要一两秒。
但无论哪种情况,传入的 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
}
但是我想知道如果操作的执行速度太快以至于调用了 setResult()
方法,会发生什么(POINT B
) 在 DeferredResult
上在将其返回(POINT A
)到调用方法之前。
Spring 是否会看到返回的 DeferredResult
已经有一个值并处理它,还是仅在实例被调用之后才开始“监视”setter 的调用提供吗?
最佳答案
我没有使用过 Spring,但会说 Class DeferredResult<>
如果结算时间对下游行为有任何影响,那么延迟实现将是一个相当糟糕的实现。
似乎可以安全地假设,无论异步进程的计时如何(毫秒、秒或其他),行为都是相同的,唯一的条件是不会发生超时,在这种情况下 onTimeout
处理程序将运行(如果设置)。即使 Deferred 是同步解决的,在创建它的同一代码块中,调用者函数也应该按预期对结果采取行动。
如果此假设无效,则 Class DeferredResult<>
不适合其用途,不应使用。
关于java - 返回可能已设置的实例时,DeferredResult 是否存在竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32094999/