Servlet3.0 servlet异步处理

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("请去邮箱查看注册结果");
	}

}

发布了127 篇原创文章 · 获赞 8 · 访问量 6275

猜你喜欢

转载自blog.csdn.net/OVO_LQ_Start/article/details/105098228