servlet线程池阻塞
servlet是单列多线程的,所有访问的请求是放在一个servlet线程池中,当访问的请求达到线程池的上限的时候,再发送的请求就会阻塞,等线程池中的请求释放后才会继续。
servlet异步处理
servlet一般工作:
1.接受解析用户请求
2.根据用户请求调用service层代码进行计算
3.将计算结果响应到客户端,释放请求。
原理:
第二步处理需要的时间较长,我们将第二步请求进行异步处理,让线程执行第一步和第三步,先释放请求,保证线程池空闲。
servlet异步处理。
package com.javaweb.servlet3.servlets;
import java.io.IOException;
import java.io.PrintWriter;
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;
import com.javaweb.servlet3.threads.ComputeThread;
@WebServlet(value="/someServlet",asyncSupported=true)
public class SomeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("主线程开始");
//获取异步上下文对象
AsyncContext as = request.startAsync();
//启动一个耗时的线程
ComputeThread ct = new ComputeThread(as);
//超时设置,超过三秒就直接执行下一步。
as.setTimeout(3000);
//开启异步上下文对象
as.start(ct);
out.println("主线程结束");
//优化用户体验,异步线程也需要时间,为了不让用户等待。
out.println("请去邮箱查看注册结果");
}
}
耗时线程
package com.javaweb.servlet3.threads;
import javax.servlet.AsyncContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class ComputeThread implements Runnable {
private AsyncContext as;
public ComputeThread(AsyncContext as) {
super();
this.as = as;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
HttpServletRequest request = (HttpServletRequest) as.getRequest();
HttpSession session = request.getSession();
int sum =0;
for(int i =0;i<10;i++){
sum+=i;
System.out.println("i="+i);
Thread.sleep(1000);
}
session.setAttribute("sum", sum);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
邮箱页面
<body>
<%
Integer sum = (Integer)session.getAttribute("sum");
if(sum == 45){
out.write("注册成功");
}else{
out.write("注册失败");
}
%>
</body>
对异步处理的监听
package com.javaweb.servlet3.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
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.javaweb.servlet3.threads.ComputeThread;
@WebServlet(value="/someServlet",asyncSupported=true)
public class SomeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("主线程开始");
AsyncContext as = request.startAsync();
ComputeThread ct = new ComputeThread(as);
as.setTimeout(3000);
as.addListener(new AsyncListener() {
@Override
public void onTimeout(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("异步超时监听");
}
@Override
public void onStartAsync(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("异步开始监听");
}
@Override
public void onError(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("异步报错监听");
}
@Override
public void onComplete(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("异步完成监听");
}
});
as.start(ct);
out.println("主线程结束");
out.println("请去邮箱查看注册结果");
}
}