何为异步请求

在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理。如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待**IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。其请求流程大致为:

而在Servlet3.0发布后,提供了一个新特性:异步处理请求。可以先释放容器分配给请求的线程与相关资源,减轻系统负担,释放了容器所分配线程的请求,其响应将被延后,可以在耗时处理完成(例如长时间的运算)时再对客户端进行响应。其请求流程为:

随着Spring5发布,提供了一个响应式Web框架:Spring WebFlux。之后可能就不需要Servlet容器的支持了。以下是其先后对比图:

原生异步请求,Servlet方式实现异步请求

注意:异步请求时,可以利用ThreadPoolExecutor自定义个线程池。

Spring方式实现异步请求

在Spring中,有多种方式实现异步请求,比如callable、DeferredResult或者WebAsyncTask。每个的用法略有不同,可根据不同的业务场景选择不同的方式。以下主要介绍一些常用的用法

Callable

控制台输出:

超时、自定义线程设置

从控制台可以看见,异步响应的线程使用的是名为:MvcAsync1的线程。第一次再访问时,就是MvcAsync2了。若采用默认设置,会无限的创建新线程去处理异步请求,所以正常都需要配置一个线程池及超时时间。

编写一个配置类:CustomAsyncPool.java

自定义一个超时异常处理类:CustomAsyncRequestTimeoutException.java

同时,在统一异常处理加入对CustomAsyncRequestTimeoutException类的处理即可,这样就有个统一的配置了。

之后,再运行就可以看见使用了自定义的线程池了,超时的可以自行模拟下:

DeferredResult

相比于callable,DeferredResult可以处理一些相对复杂一些的业务逻辑,最主要还是可以在另一个线程里面进行业务处理及返回,即可在两个完全不相干的线程间的通信。

控制台输出:

注意:返回结果时记得调用下setResult方法。

题外话:利用DeferredResult可实现一些长连接的功能,比如当某个操作是异步时,我们可以保存这个DeferredResult对象,当异步通知回来时,我们在找回这个DeferredResult对象,之后在setResult会结果即可。提高性能。

WebAsyncTask

使用方法都类似,只是WebAsyncTask是直接返回了。觉得就是写法不同而已

控制台输出:

总结

主要是讲解了异步请求的使用及相关配置,如超时,异常等处理。设置异步请求时,记得不要忘记设置超时时间。

喜欢的小伙伴,点个关注吧!

java异步处理_SpringBoot异步开发之异步请求,在高并发的情况下,提高性能相关推荐

  1. java分布式库存系统_这个是真的厉害,高并发场景下的订单和库存处理方案,讲的很详细了!...

    前言 之前一直有小伙伴私信我问我高并发场景下的订单和库存处理方案,我最近也是因为加班的原因比较忙,就一直没来得及回复.今天好不容易闲了下来想了想不如写篇文章把这些都列出来的,让大家都能学习到,说一千道 ...

  2. java 定义变量时 赋值与不赋值_探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值...

    探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值 当基本数据类型作为普通变量(八大基本类型: byte,char,boolean,short,int,long,fl ...

  3. java 基本类型 不赋值_探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值...

    探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值 当基本数据类型作为普通变量(八大基本类型: byte,char,boolean,short,int,long,fl ...

  4. java唯一订单号_java web在高并发和分布式下实现订单号生成唯一的解决方案

    方案一: 如果没有并发,订单号只在一个线程内产生,那么由于程序是顺序执行的,不同订单的生成时间戳正常不同,因此用时间戳+随机数(或自增数)就可以区分各个订单.如果存在并发,且订单号是由一个进程中的多个 ...

  5. 如何快速开发一个支持高效、高并发的分布式ID生成器(三)

    前面两个ID生成器只是简单的完成功能,如果实际应用到生产环境,则对ID生成器的要求更高,具体包括但不限于以下几点:(1) 产生全局唯一.且单调递增的ID: (2) 任何情况下ID不能重复或者回退: ( ...

  6. 2018最新阿里Java技术三面(已拿Offer):JVM+高并发性能+单点登录+微服务

    一面 1.自我介绍 2.谈一个你觉得你学到最多的项目,使用了什么技术,挑战在哪里 3.Spring的bean的作用域?(比如:singleton,prototype等) 4.Spring的IOC实现原 ...

  7. 最全Java架构师130面试题:微服务、高并发、大数据、缓存等中间件

    一.数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度. · 用Java写一个冒泡排序算法 · 描述一下链式存储结构. · 如何遍历一棵二叉树? · 倒排一个LinkedList. · 用 ...

  8. 如何快速开发一个支持高效、高并发的分布式ID生成器(一)

    ID生成器是指能产生不重复ID服务的程序,在后台开发过程中,尤其是分布式服务.微服务程序开发过程中,经常会用到,例如,为用户的每个请求产生一个唯一ID.为每个消息产生一个ID等等,ID生成器也是进行无 ...

  9. java为什么删除jpg删不掉_java-如何在不损失质量的情况下从图像(JPG)删除元数据?...

    我已经在Stackoverflow上发现了这个几乎相似的问题: 但是,当我使用上述方法时,保存的图像将被压缩.有什么办法可以在不压缩图像的情况下删除元数据?我的Java程序中可以使用任何库吗? 解决方 ...

最新文章

  1. Markdown 语法介绍
  2. 全球与中国血管重建装置市场投资现状及发展规划建议报告2022-2028年
  3. 论记笔记的重要性:以三个电影为例
  4. 拒绝无脑吹!从ACL20看预训练缺陷
  5. Java Formatter format()方法及示例
  6. i茅台app上线首日,直接冲到了App Store免费榜第一
  7. Android 渗透测试学习手册 第八章 ARM 利用
  8. 【转】URL和URI的区别
  9. java short uuid_MySQL-使用UUID_SHORT( ) 的问题
  10. matlab 画的点连成线,matlab怎么把点连成线
  11. 超详细的python语法要点思维导图,看了直呼相见恨晚,拿走不谢
  12. 【犯二记录】链表结点换位引发的思维僵化,太可怕,智商 == 0
  13. java与前端实现7种二维码
  14. 2022年下半年 系统架构师,论文-软件开发模型(Software Development Model)
  15. JAVA jdk8安装
  16. 「铭说」恶意软件分析,新版本的Danabot
  17. 一文读懂云原生数据湖体系
  18. PANGO的IOB的电平能力那些事
  19. iOS-配置AppIcon
  20. unity游戏开发_stealth秘密潜入

热门文章

  1. xshell 7 官网免费下载
  2. Qt C++属性类型提供给 QML调用(五)
  3. kafka 削峰_Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点?
  4. ARM 之三 Keil uVision4、Keil uVision5、Keil C51同一系统下的共存
  5. linux踩内存内存越界,Linux如何调试内存泄漏?超牛干货奉献给你(代码全)
  6. java函数名没有加throw_C++函数声明后面加throw()的作用
  7. vb6编写用户权限_仅需三行代码,即可让Apache Shiro接管Swagger权限认证
  8. TCP/IP / PDU 是什么
  9. JavaScript / Electron / ipcMain,ipcRenderer
  10. 模型摆完pose怎么对称_糖分过浓警告!108个情侣写真pose,太好拍了!