【问题标题】:Spring Controller waits for async response instad of managing the next requestSpring Controller 等待异步响应而不是管理下一个请求
【发布时间】:2017-04-06 20:15:01
【问题描述】:

我有这个请求端点:

@PostMapping("/verify")
public Callable<String> verify() {
    logger.debug("----STARTED REQUEST-----");
    Callable<String> callable = () -> {
        Thread.sleep(5000);
        logger.debug("_____FINISHED REQUEST_____");
        return "foo";
    };
    logger.debug("FREED CONTROLLER");
    return callable;
}

它返回一个Callable 对象,它会休眠 5 秒。

我的目标:当我有多个传入请求时,我希望它们被异步处理。

我的意思是,当第一个请求到来并且我返回一个可调用对象时,控制器应该在等待的同时处理下一个请求。但相反,它等待可调用对象完成,然后才处理下一个请求。这是日志。

[nio-8080-exec-1] c.t.c.lol.task.TaskLolController         : ----STARTED REQUEST-----
[nio-8080-exec-1] c.t.c.lol.task.TaskLolController         : FREED CONTROLLER
[      MvcAsync1] c.t.c.lol.task.TaskLolController         : _____FINISHED REQUEST_____
[nio-8080-exec-3] c.t.c.lol.task.TaskLolController         : ----STARTED REQUEST-----
[nio-8080-exec-3] c.t.c.lol.task.TaskLolController         : FREED CONTROLLER
[      MvcAsync2] c.t.c.lol.task.TaskLolController         : _____FINISHED REQUEST_____
[nio-8080-exec-5] c.t.c.lol.task.TaskLolController         : ----STARTED REQUEST-----
[nio-8080-exec-5] c.t.c.lol.task.TaskLolController         : FREED CONTROLLER
[      MvcAsync3] c.t.c.lol.task.TaskLolController         : _____FINISHED REQUEST_____

我想要什么:

----STARTED REQUEST-----
FREED CONTROLLER
----STARTED REQUEST-----
FREED CONTROLLER
----STARTED REQUEST-----
FREED CONTROLLER
_____FINISHED REQUEST_____
_____FINISHED REQUEST_____
_____FINISHED REQUEST_____

我怎样才能做到这一点?

【问题讨论】:

  • 请提供您的 MVC 配置。

标签: java spring multithreading


【解决方案1】:

从您的 callable 方法创建服务

@Service
private class TaskService {
    @Async
    public String execute() {
        try {
            Thread.sleep(5000);
            LOGGER.debug("_____FINISHED REQUEST_____");
            return "foo";
        } catch (InterruptedException e) {
            throw new RuntimeException();
        }
    }

}

在您的控制器中,将可调用对象定义为您的 `TaskService` 的执行方法

@Autowired
TaskService taskService;

@PostMapping("/verify")
public Callable<String> verify() {
    Callable<String> callable = taskservice::execute;

    logger.debug("FREED CONTROLLER");
    return callable;
}

@编辑 要使@Async 注释工作,我需要启用异步:

@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
        return Executors.newWorkStealingPool(); //will use as many threads as your processor has
    }
}

【讨论】:

  • 谢谢,它工作正常,但前提是我将 @Async 注释添加到 TaskService.execute 方法。
  • 嗯,事实上它记录正确,但是当我发送请求时,我立即得到空响应而无需等待。
【解决方案2】:

你在verify中使用Thread,例如:

Thread thread =  new Thread()
        {
            @Override
            public void run() 
            {
                System.out.println("Callable");
            }

        };
        thread.start();

【讨论】:

  • 好的,但是控制器不会等待响应。
猜你喜欢
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 1970-01-01
  • 2011-01-12
  • 2015-01-06
  • 1970-01-01
相关资源
最近更新 更多