【问题标题】:How Spring async with Callable work and what I do not understand?Spring async with Callable 如何工作以及我不明白什么?
【发布时间】:2014-12-04 16:09:47
【问题描述】:

我正在阅读 SpringMVC 文档,但我陷入了异步部分:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-async

我使用这样的控制器创建了如下非常简单的项目(Spring 4、Java 8):

@Controller
public class HomeController {

    @RequestMapping("/async")
    public Callable<String> async() {
        logger.info("Async IN, {}", new Date());
        return () -> {
            Thread.sleep(5000);
            return "home";
        };
    }

    @RequestMapping("/sync")
    public String sync() throws Exception {
        logger.info("Sync IN, {}", new Date());
        Thread.sleep(5000);
        return "home";
    }

}

我已在 Servlet 中启用异步功能 - 如文档中所述。现在我打电话给请求,首先是/sync,其次是/async。相继。他们都被立即派出。 Spring 应用程序在开始处理 /async 请求之前不会等待 /sync 结束。我在请求后的同一时间得到响应。

看起来像这样:

INFO : com.mydlarz.springtt.HomeController - Sync IN, Thu Dec 04 17:00:18 CET 2014
INFO : com.mydlarz.springtt.HomeController - Async IN, Thu Dec 04 17:00:19 CET 2014
INFO : com.mydlarz.springtt.HomeController - Async IN, Thu Dec 04 17:00:29 CET 2014
INFO : com.mydlarz.springtt.HomeController - Sync IN, Thu Dec 04 17:00:29 CET 2014

这是为什么呢?第二次请求处理不应在第一次 SYNC 后约 5 秒开始?

【问题讨论】:

    标签: java spring spring-mvc asynchronous


    【解决方案1】:

    同步和异步是相对于 Servlet 容器使用的线程而言的。同步请求将用完该线程,并在必要时阻塞它以完成其他操作。一个异步请求,会用完线程,但不会阻塞它。操作将转移到另一个可能发生阻塞的线程。

    这是为什么呢?第二次请求处理不应在第一次 SYNC 后约 5 秒开始?

    如果您的 Servlet 容器中有超过 4 个线程(很可能),则您的 4 个请求都不会等待任何其他请求。

    【讨论】:

    • @DariuszMydlarz 没有标准的方法。这取决于您的 Servlet 容器。
    • @DariuszMydlarz 模拟备份请求的方法是在每个方法前添加synchronized,即public synchronized String sync()。但不要将synchronized 留在生产环境中。
    猜你喜欢
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多