在Servlet的原始版本中,假设浏览器同时有多个请求发送到服务器,web服务器在处理第一个请求时,若处理占用时间较长,则其他请求在这第一个请求被处理的时间段内无法进行任何操作。
被阻塞的Servlet请求过程:
Servlet3.0有了新特性异步处理,所谓异步处理就是指数据发送方发送数据给数据接收方后,不必等待数据接收方作出响应,可以继续发送下一个数据的通信方式,Servlet 3.0版本提供了相关异步处理的功能,具体实现方式如下:
-
需要使用注解在对应Servlet配置asyncSupported=true,表示当前Servlet支持异步。
-
通过Request对象的startAsync(Request, Response)方法获取异步上下文对象。
-
通过异步上下文对象调用start(new Runnable(){})方法开始异步处理,Runnable类的run()方法提供具体异步的逻辑代码。
Servlet异步处理流程:
演示:
package com;
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;
/**
- Servlet implementation class AsyncDemoServlet
*/
@WebServlet(urlPatterns = “/AsyncDemoServlet”, asyncSupported = true)
public class AsyncDemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
- @see HttpServlet#HttpServlet()
*/
public AsyncDemoServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
-
@see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
-
response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html; charset=UTF-8”);
PrintWriter out = response.getWriter();
out.print(“
进入servlet时间” + new Date().toLocaleString() + “
”);AsyncContext asctx = request.startAsync();
new Thread(new Executor(asctx)).start();
out.print(“
退出servlet时间” + new Date().toLocaleString() + “
”);out.flush();
}
/**
-
@see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
-
response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
class Executor implements Runnable {
private AsyncContext ctx = null;
public Executor(AsyncContext asCtx) {
ctx = asCtx;
}
@Override
public void run() {
try {
Thread.sleep(10000);
PrintWriter out = ctx.getResponse().getWriter();
out.print(“
子线程执行完毕” + new Date().toLocaleString() + “
”);out.flush();
ctx.complete();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其中:
(1)在”WebServlet“注释中配置属性支持异步操作:@WebServlet(urlPatterns = "/AsyncDemoServlet", asyncSupported = true)
;
(2)创建子线程构建耗时操作:
class Executor implements Runnable {
private AsyncContext ctx = null;
//借助构造方法进行传参
public Executor(AsyncContext asCtx) {
ctx = asCtx;
}
@Override
//线程真正的操作在run方法中
public void run() {
try {
//模拟耗时操作
Thread.sleep(10000); //睡10秒
PrintWriter out = ctx.getResponse().getWriter();
out.print(“
子线程执行完毕” + new Date().toLocaleString() + “
”);out.flush();
ctx.complete();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(3)主线程:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html; charset=UTF-8”);
PrintWriter out = response.getWriter(); //记录进入时间
out.print(“
进入servlet时间” + new Date().toLocaleString() + “
”);AsyncContext asctx = request.startAsync();
new Thread(new Executor(asctx)).start(); //启动线程
out.print(“
退出servlet时间” + new Date().toLocaleString() + “
”);out.flush();
}
运行
仍在执行请求
进入与退出时间基本一致,主线程不会产生线程阻塞
Servlet基础总结:
-
Servlet是运行在Servlet容器中的Java类,它能处理Web客户的HTTP请求,并产生HTTP响应;
-
Servlet技术具有高效、方便、功能强大、可移植性好等特点;
-
Servlet接口规定了必须由Servlet类实现并且由Servlet引擎识别和管理的方法集;
-
Servlet API包含两个软件包: javax.servlet包和javax.servlet.http包;
-
简单地扩展GenericServlet和实现service()方法就可以编写一个基本的 Servlet,但若要实现一个在Web中处理HTTP的Servlet,则需要继承HttpServlet类;
-
Servlet生命周期是指Servlet实例从创建到响应客户请求直至销毁的过程;
-
Servlet的生命周期按照七种状态间的转换,可分为四个阶段:加载和实例化、初始化、处理请求、终止服务;
-
Servlet既可使用注解@WebServlet进行配置,也可在web.xml文件中配置;
-
在Servlet中可以通过两种主要方式完成对新URL地址的转向:重定向和请求转发;
-
Servlet 3.0较之前版本,新增了注解支持、可插性支持、动态配置和异步处理等新特性。
最后
小编这些年深知大多数初中级工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Java全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你需要这些资料,⬅专栏获取
小编这些年深知大多数初中级工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
因此我收集整理了一份《2024年Java全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-bT0qAIYB-1719510554807)]
[外链图片转存中…(img-ljsiLGEk-1719510554808)]
[外链图片转存中…(img-hG8aAQhR-1719510554809)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你需要这些资料,⬅专栏获取