先看一个简单的示例:

 @RequestMapping("/getFuture")
public Future<String> getFuture() {
System.out.println(1);
// 必须是ListenableFuture的子类,或者CompletionStage子类,或者是DeferredResult 不能是FutureTask
// 如何返回CompletableFuture
CompletableFuture<String> ftu2 = CompletableFuture.supplyAsync(() -> {
try {
// RequestContextHolder.setRequestAttributes(attributes);
// 使用ThreadLocal相关特性时,需要在外面先get
Thread.sleep(3000L);
} catch (InterruptedException e) {
} finally {
// RequestContextHolder.resetRequestAttributes();
}
return "THIS string";
}, es); //Future<String> future = executorService.submit(() -> { }); //返回值是FutureTask return ftu2;
}


客户端发起请求
===> DispatcherServlet根据返回值类型查找对应的handlar AsyncHandlerMethodReturnValueHandler
【Callable -->
CallableMethodReturnValueHandler; DeferredResult,CallableFuture,ListenableFuture --> DeferredResultMethodReturnValueHandler】
===> Controller中返回Future对象给容器, 
org.springframework.web.context.request.async.WebAsyncManager#startDeferredResultProcessing处理Future结果的监听 ===>
sleep3秒之后,Future完成后调用asyncWebRequest.dispatch() 重新发给Container,DispatcherServlet找到Message的序列化器将结果输出。DispatcherServlet.doService会进入两次!!!
异步线程的主要功能是: 
业务处理耗较长(上面的sleep3)时,可以先返回Future对象释放Container的work线程, work线程可以接收更多的请求。等Future完成之后重新调用Container的另一个work线程,输出response. 这里work线程可以是BIO中work线程, 也可以是NIO中work线程 不是所有的Future都能在异步线程中处理
https://www.cnblogs.com/dennyzhangdd/p/7010972.html spring boot中配置container的work线程数量
server.tomcat.max-threads=5
server.tomcat.min-spare-threads=3
 
使用异步处理的优点:
增加系统吞吐量,对响应速度提高不大,可能还会降低
缺点:
线程关系复杂, 异步超时、异常日志拦截需要实现具体的Adapter接口,threadLocal不好清理 参考:《亿级流量架构核心技术》http://jinnianshilongnian.iteye.com/blog/2245925
Servlet3.1 规范
    tomcat线程配置 https://www.cnblogs.com/kismetv/p/7806063.html
遗留问题: Future.get是什么时候调用的?
没有直接调用get。 ListenerableFuture, CompletableFuture任务完成之后都会触发回调 work1线程: 接收到请求---> DispatcherServlet--> return future -->WebAsyncManager#startDeferredResultProcessing
自定义的任务线程: CompletableFuture.postComplete之后调用 WebAsyncManager#setConcurrentResultAndDispatch
work2线程: dipatch ---> DispatcherServlet --> response.out 关于第二个任务线程
当返回值是Callable时,调用WebAsyncManager#startCallableProcessing, 此时任务线程使用的是AsyncTaskExecutor,
可以通过org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#configureAsyncSupport设置自定义的AsyncTaskExecutor 当返回值是DeferredResult,ListenableFuture (Spring提供),CompletableFuture(JDK自带)时,调用WebAsyncManager#startDeferredResultProcessing,此时任务线程池可以直接指定
@See CompletableFuture.supply(xxxTask, threadPool)
@RequestMapping("/callableTest")
public Callable<String> callableTest() {
Callable<String> hello = () -> {
// 此处不能设置线程池, WebAsyncManager中会使用AsyncSupportConfigurer的线程池
System.out.println("===>" + Thread.currentThread().getName());
return "HELLO";
};
return hello;
}
												

SpringMVC DeferedResult和servlet3.1 AsyncContext异步请求的更多相关文章

  1. 深入理解Servlet3.0异步请求

    异步请求的基础概念 异步请求最直接的用法就是处理耗时业务,Http协议是单向的,只能客户端拉不能服务器主推. 异步请求的核心原理主要分为两大类:1.轮询.2长连接 轮询:就是定时获取返回结果. 长连接 ...

  2. 15.SpringMVC之异步请求

    SpringMVC中异步请求相关组件 SpringMVC在此基础上对异步请求进行了封装.提供了AsyncWebRequest类型的request,并提供了处理异步请求的管理器WebAsyncManag ...

  3. 天天写同步,5种SpringMvc异步请求了解下!

    引言 说到异步大家肯定首先会先想到同步.我们先来看看什么是同步? 所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作. 简单来说,同步就是必须一件一件事做,等前一件 ...

  4. springmvc webservlet 异步请求总结

    1:每次请求会启动一个新线程 上边在debug状态下, 每次请求一次,生成一个新的 thread  在此已经是245了 出现一个现象在debug模式下, 每次请求生成的线程,自动在红框那个位置停了下来 ...

  5. Springmvc中 同步/异步请求参数的传递以及数据的返回

    转载:http://blog.csdn.net/qh_java/article/details/44802287 注意: 这里的返回就是返回到jsp页面 **** controller接收前台数据的方 ...

  6. Filter 快速开始 异步Servlet 异步请求 AsyncContext 异步线程 异步派发 过滤器拦截

    [web.xml] <filter> <filter-name>normalFilter</filter-name> <filter-class>net ...

  7. springmvc中同步/异步请求参数的传递以及数据的返回

    注意: 这里的返回就是返回到jsp页面 **** controller接收前台数据的方式,以及将处理后的model 传向前台***** 1.前台传递数据的接受:传的属性名和javabean的属性相同 ...

  8. 【坑】前端使用ajax异步请求以后,springMvc拦截器跳转页面无效

    文章目录 前言 `$.ajaxSetup( )` 后记 前言 本文着重解决前后端分离开发的页面调整问题. 笔者,在做一个需求,需要对访问网站,但是没有登录的用户进行拦截,将他们重定向到首页. 很简单的 ...

  9. 使用Callable或DeferredResult实现springmvc的异步请求

    使用Callable实现springmvc的异步请求 如果一个请求中的某些操作耗时很长,会一直占用线程.这样的请求多了,可能造成线程池被占满,新请求无法执行的情况.这时,可以考虑使用异步请求,即主线程 ...

随机推荐

  1. 【总结整理】display、visibility、overflow的隐藏问题

    display.visibility.overflow的隐藏问题 http://blog.sina.com.cn/s/blog_85e7c239010151r4.html   display:bloc ...

  2. poj2287 Tian Ji -- The Horse Racing

    传送门 分析 这个题和传统的田忌赛马不一样的地方就是多了平局情况,所有我们不难想到要用dp.我们先将两人的马均降序排列,用dpij表示考虑前i匹马,田忌有几匹马是按从大到小的顺序从头取的(剩下的是从尾 ...

  3. cximage使用

    为什么使用CxImage u 使用简单:下面的入门教程会给你展示这一点. 构造函数 初始化 多帧图像操作 区域选择操作 Alpha通道操作 Layers 图像层操作 Attributes 图像属性操作 ...

  4. 37LCD-TFTLCD原理与配置

    1.TFTLCD驱动原理 简介

  5. Entity Framework Code-First(21):Automated Migration

    Automated Migration: Entity framework 4.3 has introduced Automated Migration so that you don't have ...

  6. Mac下的UI自动化测试 (二)

    下面讲一下Sikuli的重要概念,就是region,所谓region就是Sikuli在进行图像识别的时候的一个区域,默认是整个屏幕. 当然,如果region选得太大的话,并且UI上存在相似的控件,那么 ...

  7. C#提取TXT文档指定内容

    早上有分享一篇<VB.NET提取TXT文档指定内容> http://www.cnblogs.com/insus/p/3267347.html 那是原网友的需求用VB.NET写的.刚才有只懂 ...

  8. unity网络延迟

    using UnityEngine; using System.Collections; public class Test_Ping : MonoBehaviour { public string ...

  9. Cardinality (基数)

    名词 Cardinality:    优化器在计算成本的时候,需要从统计信息中取得数据,然后去估计每一步操作所涉及的行数,叫做Cardinality.    比如,一张表T有1000行数据,列COL1 ...

  10. C# 添加,修改,删除Xml节点

    //添加xml节点    private void AddXml(string image, string title)     {        XmlDocument xmlDoc = new X ...