有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    我没有使用Spring,但我会说,如果结算时间对下游行为有任何影响,那么Class DeferredResult<>将是延迟的一个相当糟糕的实现

    似乎可以安全地假设,无论异步进程的计时是毫秒、秒还是其他时间,行为都是相同的,唯一的条件是没有发生超时,在这种情况下onTimeout处理程序将运行(如果设置)。即使延迟被同步解决,在创建它的同一代码块中,调用方函数也应该按照预期对结果进行操作

    如果这个假设无效,那么Class DeferredResult<>就不适合使用,不应该使用