异步Servlet为什么能提高并发? 5C

异步Servlet为什么能提高并发?有点不明白异步化之后虽然tomcat中的tomcat connector接收线程少了,但业务线程还是一样的呀,那为什么不直接调大tomcat的线程数

davy2495
davy2495 servlet的io瓶颈了解一下
10 个月之前 回复

2个回答

因为有些代码调用会造成线程阻塞。比如说,调用一个远程的api,那么当你请求发出,等待对方返回数据的时候,你的服务器(如果是同步的话)就无事可做了。
此时如果有新的请求,只能排队等着,而当前的程序也不能往下执行。
而异步就可以解决这个问题,一个请求阻塞的时候,服务器可以同时处理别的请求。
为什么不直接调大tomcat的线程数,因为同步的请求,Servlet的非静态成员和方法都需要同步的,你的线程再多,也不能并发,只能等着。

   首先你得理解什么是 高并发,其实用白话说,高并发就是 在某一时间段里有大量的用户访问你的网站,从而产生大量的流量,因为你要相应数据嘛。

那么如果 用户访问量 很大,你的服务器就需要处理大量的请求,而每一个请求都是需要用一个线程去处理的,也就是Tomcat需要提供一个线程去处理
你的请求(Tomcat有内置的线程池)。
    那为什么说Servlet 异步能提高并发量呢? 也就是说为什么Servlet异步时为什么能提高对用户请求的处理响应时间?
         这时候你需要了解 异步的概念:在Java中异步用白话文讲就是指的同时干多件事(如人一心两用),其实也就是多线程的概念。
        那用Servlet来解释就是,在Servlet 3.0 后版本默认异步,也就是说在Servlet 3.0 之前版本,如果同一时间有两个用户同时向你
        的Servlet发送同一个请求时,Servlet 只能先处理一个,另一个就得等着前一个先处理完之后它才能得到处理,用通俗的话讲就是排队(不过具体谁先谁后就看它们谁先抢到CPU资源了)。

        那在Servlet 3.0之后呢,Servlet变成 “异步”的了,也就是这时候如果还是同事有两个请求过来,Servlet能同时处理了,通俗的将就是变成两个人处理了,之前只有一个人处理,自然需要排队,这里的“人”就是 “线程”。也就是在Servlet 3.0之前是单线程的,到了Servlet 3.0之后进行了优化,内部使用多线程实现异步处理请求。具体的还需你自己查阅文章、源码进行理解。

其中涉及到了异步和阻塞的区别、多线程、IO、NIO(包括BIO、NIO、AIO)等等概念。


Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Servlet3.0新特性之异步处理

我想测试的是setTimeout后,当异步线程超时会有什么结果,第一次打开算正常![图片说明](https://img-ask.csdn.net/upload/201704/19/1492585407_488230.png)但刷新之后就变成这样子。![图片说明](https://img-ask.csdn.net/upload/201704/19/1492585485_486937.png)困扰了好久,求大神解答一下 代码如下: ``` package test11; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns="/test1", asyncSupported=true) public class test1 extends HttpServlet { private static final long serialVersionUID = 1L; public test1() { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); //开始时间 out.println(new Date() + "<br/>"); AsyncContext asyncContext = request.startAsync(); //设置超时时间0.5秒 asyncContext.setTimeout(500); //开始异步处理 asyncContext.start(new Run(asyncContext)); //结束时间 out.println(new Date()+ "<br/>"); out.flush(); } } class Run implements Runnable { private AsyncContext asyncContext; public Run(AsyncContext asyncContext) { this.asyncContext = asyncContext; } @Override public void run() { PrintWriter out = null; HttpServletRequest httpServletRequest = null; try { httpServletRequest = (HttpServletRequest) asyncContext.getRequest(); HttpServletResponse httpServletResponse = (HttpServletResponse) asyncContext.getResponse(); out = httpServletResponse.getWriter(); //打印异步开始标志in out.println("in"+ "<br/>"); //睡眠1秒,代表耗时的业务方法 Thread.sleep(1000); //业务方法完成,打印完成标记out out.println("out"+ "<br/>"); //输出完成时间 out.println(new Date()+ "<br/>"); asyncContext.dispatch("/index.jsp"); } catch (Exception e) { e.printStackTrace(); } } } ```

mongoose异步操作mongodb,在高并发的情况下数据安全吗?

因为mongoose操作数据库数据是异步的,那么当我连续进行添加更新查询等操作,且高并发的情况下,数据是正确的吗?还是说他内部机制,还是有个队列一个一个执行的。

Servlet3中的AsyncContext异步和多线程异步有什么区别

我如果想异步向页面输出,则可以使用Servlet3中的AsyncContext。也可以在Servlet中另外启动一个多线程处理,让主线程先返回页面 两种方式的代码如下 [code="java"] public class ListServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("I am begin output !"); response.getWriter().flush(); //方式一 AsyncContext async = request.startAsync(); new AsyncOutput(async).start(); //方式二 new ThreadOutput(response).start(); response.getWriter().println("I am finash output !"); response.getWriter().flush(); } } class AsyncOutput extends Thread { private AsyncContext async; public AsyncOutput(AsyncContext async) { this.async = async; } public void run() { try { Thread.sleep(3000); async.getResponse().getWriter().println("I was three minutes late !"); async.getResponse().getWriter().flush(); }catch(Exception e) { e.printStackTrace(); } } } class ThreadOutput extends Thread { private HttpServletResponse response; public ThreadOutput(HttpServletResponse response) { this.response = response; } public void run() { try { Thread.sleep(3000); response.getWriter().println("I was three minutes late !"); response.getWriter().flush(); }catch(Exception e) { e.printStackTrace(); } } } [/code] 这两种效果是一样啊 既然如此,那还搞什么AsyncContext AsyncContext有什么不一样的地方 以上两种使用方式,有什么区别? 求指点

有关servlet获取form表单数据的异步刷新问题

servlet如何实现从form表单获取数据条件是异步提交的方式,有大神发个简单的小例子小弟感激不禁!!谢谢了

关于支付系统中的同步通知和异步通知电商的区别,为什么需要通知

在电商对应的支付系统中当支付完成之后需要做相关的同步通知和异步通知操作,请大神解释一下什么是同步通知和异步通知,为什么需要同步通知和异步通知。

asp.net webform 异步操作数据库是不是会引起并发问题啊?

asp.net,有一个审批操作,需要大量的计算,然后更新数据库,如果使用同步的话,等待的时间有点长,我改用委托去实现异步,但是在多个人同时审批的时候,有出现数据更新不全或者数据丢失问题,百度了一下,有说是asp。net异步操作数据库会有并发,会引起逻辑错误,是这样的吗?请问有谁遇到过呢?如果是这样,有好的解决方案吗?

servlet3.0 异步更新数据库的实现

package com.lpmas.mkt.console.campaign.taurus.action; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lpmas.admin.business.AdminUserHelper; import com.lpmas.admin.config.OperationConfig; import com.lpmas.framework.web.HttpResponseKit; import com.lpmas.mkt.console.campaign.taurus.bean.UserRepresentBean; import com.lpmas.mkt.console.campaign.taurus.business.UserRepresentInfoBusiness; import com.lpmas.mkt.console.campaign.taurus.config.MktConsoleConfig; import com.lpmas.mkt.console.campaign.taurus.config.MktResource; @WebServlet(urlPatterns = "/campaign/UserRepresentRefresh.do", asyncSupported = true) public class UserRepresentRefresh extends HttpServlet { private static final long serialVersionUID = 2218434995334526228L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AdminUserHelper adminHelper = new AdminUserHelper(request, response); if (!adminHelper.checkPermission(MktResource.CAMPAIGN_INFO, OperationConfig.SEARCH)) { return; } int userId = Integer.valueOf(request.getParameter("userId")); UserRepresentInfoBusiness userRepresentInfoBusiness = new UserRepresentInfoBusiness(); UserRepresentBean resultBean = userRepresentInfoBusiness.createValidRepresentInfo(userId); request.setAttribute("AdminUserHelper", adminHelper); String path = MktConsoleConfig.PAGE_PATH + "UserRepresentList.jsp"; if (resultBean != null) { HttpResponseKit.alertMessage(response, "处理成功", path); }else{ HttpResponseKit.alertMessage(response, "处理失败", HttpResponseKit.ACTION_HISTORY_BACK); } } } 这样算不算异步? userRepresentInfo是更新数据库的操作 HttpResponseKit.alertMessage是弹出信息

关于Servlet多线程的问题

Servlet是单实例多线程的,所以我就做了一个小的测试验证这种模式,很简单, class DemoServlet extends HttpServlet { public void doGet(......) { System.out.println("come in."); Thread.sleep(10 * 1000); } } 然后在浏览器多个地址栏同时请求这个servlet,发现必须第前面的请求结束,后面的请求才可以进入doGet方法,实在搞不懂为什么,求大神帮解答下!! 另外,关于异步Servlet的也是如此,必须等前面请求的AsyncContext.complete()之后,后面的请求才能进doGet方法,这还算多线程吗?

ajax异步操作页面还是跳转怎么办

用jsp写查询功能,输入学生ID查出其详细信息。 我一开始用form表单提交数据给servlet,提交的时候会跳转页面,所以我就用了ajax异步,但是用了ajax把数据提交给servlet还是会跳转页面到servlet,我觉得可能是因为只要我提交给serlvet就会引起刷新对不对?但是不提交给servlet我提交给谁呢?(ajax的路径我写了servlet的)

jsp/servlet异步处理机制-为什么减轻了Web容器负担,节约了系统资源

最近在研究servlet的异步处理机制时,有人说异步处理释放了处理请求的线程,**能节约系统资源**,但同时又开启了另一个线程延迟处理了呀,所以对于servlet异步处理节约资源这种说法,我是不是哪里理解错了呀,有哪位能够讲解下不,谢谢

关于支付系统中同步通知和异步通知时什么为什么需要同步通知和异步通知

在电商发起订单支付中到支付系统支付完成之后 为什么需要发送同步通知或者异步通知,什么是同步通知什么又是异步通知,请大神赐教!

servlet3异步推送的问题

我如何在线程里得到的数据传送给异步线程监听,直至前台响应? 目前 只能通过浏览器经过HTTP请求的方式实现推送响应。 目前的困难是mina server端获取到消息,怎么才能前台响应。

python2.7 异步代理,能给一个例子吗?

python2.7 异步代理,能给一个例子吗?包含客户端,代理服务器,还有服务器的

如何提高单台tomcat的并发能力

说实话,这个问题困扰我很多年,无奈公司团队当中也无人能为我解答这个问题,言归正传,自己曾今用jmeter测试过,在一台linux 8核服务器,内存为16GB,安装一台tomcat,然后部署一个自己写的简单Java web服务,提供一个非常简单的restful api,然后通过jmeter进行压测,发现当并发请求数达到四五千的时候tomcat就支撑不住了,难道一台机器只能支撑四五千的并发量?

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争,请问是这样的吗? 谢谢了。

刚学习,麻烦大神看下,我的ajax异步servlet回调函数得不到值

$(function() {// 使用AJAX获取列表数据 $(".views").on("click",function(){ var sickId=$(this); $.ajax({ url : "sickInfoServlet", type : "GET", data : {sickId:sickId.attr("ide")}, dataType : "json", success : function(result){ alert(result.sickId); $("#v_sickId").val(result.sickId); $("#v_hospitalId").val(result.hospitalId); $("#v_sickBedId").val(result.sickBedId); $("#v_doctorId").val(result.doctorId); $("#v_nurseId").val(result.nurseId); $("#v_sickName").val(result.sickName); $("#v_sickSex").val(result.sickSex); $("#v_sickAge").val(result.sickAge); $("#v_inresult").val(result.inresult); if(result.outresult==null){ $("#v_outresult").val("未出院"); }else{ $("#v_outresult").val(result.outresult); } $("#v_sickAddress").val(result.sickAddress); $("#v_sickPhone").val(result.sickPhone); $("#v_leaveHospital").val(result.leaveHospital); $("#v_cash").val(result.cash); }, error : function(xmlhttprequest) { alert("出现未知错误,查看失败"); alert(xmlhttprequest.status); alert(xmlhttprequest.readyState); } }); }); }); // servlet package com.hospital.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hospital.po.InHospital; import com.hospital.profesachieve.SickInfoServiceImpl; public class SickInfoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 编码集处理 req.setCharacterEncoding("UTF-8"); resp.setContentType("application/json;charset=utf-8"); // 接收前端页面的消息 String sickId=req.getParameter("sickId"); System.out.println("传入的值sickId:"+sickId); PrintWriter out=resp.getWriter(); // 处理SickInfo InHospital i= new SickInfoServiceImpl().view(sickId); //将上述对象集合封装成json格式进行输出 StringBuffer Json=new StringBuffer("["); Json.append("{\"sickId\":\""+i.getSickId()+"\","); Json.append("\"hospitalId\":\""+i.getHospitalId()+"\","); Json.append("\"sickBedId\":\""+i.getSickBedId()+"\","); Json.append("\"doctorId\":\""+i.getDoctorId()+"\","); Json.append("\"nurseId\":\""+i.getNurseId()+"\","); Json.append("\"sickName\":\""+i.getSickName()+"\","); Json.append("\"sickSex\":\""+i.getSickSex()+"\","); Json.append("\"sickAge\":\""+i.getSickAge()+"\","); Json.append("\"inData\":\""+i.getInData()+"\","); Json.append("\"outData\":\""+i.getOutData()+"\","); Json.append("\"sickAddress\":\""+i.getSickAddress()+"\","); Json.append("\"sickPhone\":\""+i.getSickPhone()+"\","); Json.append("\"leaveHospital\":\""+i.getLeaveHospital()+"\","); Json.append("\"cash\":\""+i.getCash()+"\"}"); Json.append("]"); String res =new String(Json); System.out.println("生成的res:"+res); out.print(res); out.close(); } // 前端 <div > <p> 患者编号:<input type="text" name="sickId" id="v_sickId" readonly value=""/> 医院编号:<input type="text" name="hospitalId" id="v_hospitalIdd" readonly value=""/> 患者名字:<input type="text" name="sickName" id="v_sickName" readonly value=""/> </p> <p> 患者性别:<input type="text" name="sickSex" id="v_sickSex" readonly value=""/> 患者年龄:<input type="text" name="sickAge" id="v_sickAge" readonly value=""/> 住院时间:<input type="text" name="inData" id="v_inData" readonly value=""/> </p> <p> 出院时间:<input type="text" name="outData" id="v_outData" readonly value=""/> 患者地址:<input type="text" name="sickAddress" id="v_sickAddress" readonly value=""/> 联系电话:<input type="text" name="sickPhone" id="v_sickPhone" readonly value=""/> </p> <p> 离院备注:<input type="text" name="leaveHospital" id="v_leaveHospital" readonly value=""/> 住院押金:<input type="text" name="cash" id="v_cash" readonly value=""/> </p> </div> 点击查询后可以正常执行servlet生成json格式数据生成的res:[{"sickId":"1336565555","hospitalId":"741852963","sickBedId":"105003","doctorId":"20307","nurseId":"20102","sickName":"闫晓丽","sickSex":"女","sickAge":"36","inData":"2020-04-01","outData":"null","sickAddress":"陕西","sickPhone":"18062542369","leaveHospital":"null","cash":"200.0"}],但是到sucess中alert弹窗获取到的值为undefined,前端页面也没有加载出来值,浏览器未报错。

ajax文件下载异步处理

最近在做一个下载更新程序,界面使用的是jsp,servlet提供服务,在文件下载使用ajax异步操作时遇到了相关的问题,不知道如何解决,请高手帮忙,谢谢! 问题描述:点击下载按钮时,希望页面部分刷新,只要显示下载进度的文本框就好了。

关于如何模拟高并发,这是我在网上看到的一个,请问这样算是高并发模拟吗?

``` <title>参数</title> <!-- 加载Query文件--> <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.0.js"> </script> <script type="text/javascript"> $(document).ready(function () { //模拟10000个异步请求,进行并发 //真正对数据库存储产生影响的是为user用户的stock数量 var max = 15000; for (var i = 1; i <= max; i++) { //jQuery的post请求,请注意这是异步请求 $.post({ //根据自己请求修改对应的url // url: "./question/insertQuestionByRedis.do?times="+i+"&userId=1&question=问题"+i.toString()+"&answer=答案", //使用redis url: "./question/insertQuestion.do?userId=1&question=问题"+i+"&answer=答案", //没有使用Redis //成功后的方法 success: function (result) { } }); } }); </script> ``` 利用for循环异步提交,但是for循环是一个一个来的,有点不太懂,请求大佬解答下。

Servlet3.0 AsyncContext 问题。

书上写“ 被异步请求dispatch的目标页面需要指定session=“false" ”。想知道为什么要这样做?禁用session的意义是什么。 初学者,很多地方不太了解。

YOLOv3目标检测实战:训练自己的数据集

YOLOv3目标检测实战:训练自己的数据集

150讲轻松搞定Python网络爬虫

150讲轻松搞定Python网络爬虫

实用主义学Python(小白也容易上手的Python实用案例)

实用主义学Python(小白也容易上手的Python实用案例)

我说我不会算法,阿里把我挂了。

不说了,字节跳动也反手把我挂了。

立方体线框模型透视投影 (计算机图形学实验)

计算机图形学实验 立方体线框模型透视投影 的可执行文件,亲测可运行,若需报告可以联系我,期待和各位交流

2019 AI开发者大会

2019 AI开发者大会

组成原理课程设计(实现机器数的真值还原等功能)

实现机器数的真值还原(定点小数)、定点小数的单符号位补码加减运算、定点小数的补码乘法运算和浮点数的加减运算。

C/C++跨平台研发从基础到高阶实战系列套餐

一 专题从基础的C语言核心到c++ 和stl完成基础强化; 二 再到数据结构,设计模式完成专业计算机技能强化; 三 通过跨平台网络编程,linux编程,qt界面编程,mfc编程,windows编程,c++与lua联合编程来完成应用强化 四 最后通过基于ffmpeg的音视频播放器,直播推流,屏幕录像,

MFC一站式终极全套课程包

该套餐共包含从C小白到C++到MFC的全部课程,整套学下来绝对成为一名C++大牛!!!

软件测试2小时入门

软件测试2小时入门

三个项目玩转深度学习(附1G源码)

三个项目玩转深度学习(附1G源码)

计算机图形学-球的光照模型课程设计

计算机图形学-球的光照模型,有代码完美运行,有课程设计书

Linux常用命令大全(非常全!!!)

Linux常用命令大全(非常全!!!) 最近都在和Linux打交道,感觉还不错。我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,比较短小但却功能强大。我将我了解到的命令列举一下,仅供大家参考: 系统信息 arch 显示机器的处理器架构 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 d...

因为看了这些书,我大二就拿了华为Offer

四年了,四年,你知道大学这四年我怎么过的么?

深度学习原理+项目实战+算法详解+主流框架(套餐)

深度学习系列课程从深度学习基础知识点开始讲解一步步进入神经网络的世界再到卷积和递归神经网络,详解各大经典网络架构。实战部分选择当下最火爆深度学习框架PyTorch与Tensorflow/Keras,全程实战演示框架核心使用与建模方法。项目实战部分选择计算机视觉与自然语言处理领域经典项目,从零开始详解算法原理,debug模式逐行代码解读。适合准备就业和转行的同学们加入学习! 建议按照下列课程顺序来进行学习 (1)掌握深度学习必备经典网络架构 (2)深度框架实战方法 (3)计算机视觉与自然语言处理项目实战。(按照课程排列顺序即可)

fakeLocation13.5.1.zip

fakeLocation13.5.1 虚拟定位 ios13.5.1的最新驱动下载,iPhone/iPad免越狱虚拟定位工具Location-cleaned驱动已更新

UnityLicence

UnityLicence

Python可以这样学(第一季:Python内功修炼)

Python可以这样学(第一季:Python内功修炼)

Python+OpenCV计算机视觉

Python+OpenCV计算机视觉

土豆浏览器

土豆浏览器可以用来看各种搞笑、电影、电视剧视频

【数据结构与算法综合实验】欢乐连连看(C++ & MFC)案例

这是武汉理工大学计算机学院数据结构与算法综合实验课程的第三次项目:欢乐连连看(C++ & MFC)迭代开发代码。运行环境:VS2017。已经实现功能:开始游戏、消子、判断胜负、提示、重排、计时、帮助。

php+mysql学生成绩管理系统

学生成绩管理系统,分三个模块:学生,教师和管理员。 管理员模块:负责学生、老师信息的增删改;发布课程信息的增删改,以便让学生选课;审核老师提交的学生成绩并且打印成绩存档;按照课号查询每个课号的学生成绩

多功能数字钟.zip

利用数字电子计数知识设计并制作的数字电子钟(含multisim仿真),该数字钟具有显示星期、24小时制时间、闹铃、整点报时、时间校准功能

推荐24个国外黄色网站欣赏

在中国清朝,明黄色的衣服只有皇子才有资格穿,慢慢的黄色在中国就成了高贵的颜色。在人们的色彩印象中,黄色也表现为暂停。所以当你的网页设计采用黄色的时候,会让人们在你的网页前停留。 黄色,就像橙色和红色,黄色也是一个暖色。它有大自然、阳光、春天的涵义,而且通常被认为是一个快乐和有希望的色彩。黄色是所有色相中最能发光的颜色,给人轻快,透明,辉煌,充满希望的色彩印象。 黄色是一个高可见的色...

u-boot-2015.07.tar.bz2

uboot-2015-07最新代码,喜欢的朋友请拿去

一学即懂的计算机视觉(第一季)

一学即懂的计算机视觉(第一季)

学生成绩管理系统(PHP + MYSQL)

做的是数据库课程设计,使用的php + MySQL,本来是黄金搭配也就没啥说的,推荐使用wamp服务器,里面有详细的使用说明,带有界面的啊!呵呵 不行的话,可以给我留言!

Windows版YOLOv4目标检测实战:训练自己的数据集

Windows版YOLOv4目标检测实战:训练自己的数据集

C++语言基础视频教程

C++语言基础视频教程

玩转Python-Python3基础入门

玩转Python-Python3基础入门

相关热词 c# 按行txt c#怎么扫条形码 c#打包html c# 实现刷新数据 c# 两个自定义控件重叠 c#浮点类型计算 c#.net 中文乱码 c# 时间排序 c# 必备书籍 c#异步网络通信
立即提问