tomcat7特性 serlvet async特性ITeye - AG环亚娱乐集团

tomcat7特性 serlvet async特性ITeye

2019-01-10 21:00:44 | 作者: 康震 | 标签: 处理,线程,恳求 | 浏览: 1252

 

每个恳求来到Web容器,Web容器会为其分配一个线程来专门担任该恳求,直到完结处理前,该履行线程都不会被开释回容器。 履行线程会耗用体系资源,若有些恳求需求长期处理(例如长期运算、等候某个资源),就会长期占用履行线程。 
若这类的恳求许多,许多履行线程都被长期占用,而在web容器内,能够运用的线程都是有限的,这关于体系就会是个担负,乃至形成应用程式的功用瓶颈。

基本上一些需长期处理的恳求,一般客户端也较不在乎恳求后要有当即的回应。若能够,让这类恳求先开释容器分配给该恳求的履行线程,让容器能够有机会将履行线程资源分配给其它的恳求,能够减轻体系担负。

许多项目在遇到需长期处理的使命时,常常启一个新线程或许扔到线程池中,这样不耽搁使命主线的流程,这个servlet的asynch特性其实发挥相同的效果

开释了容器所分配履行线程的恳求,其回应将被拖延,直到处理完结(例如长期运算完结、所需资源已获得)再行对客户端的回应,假如超越浏览器的链接时长,会将servlet中的内容回来,而asyncContext中的内容则不能回来,效劳器抛出java.lang.IllegalStateException过错

在Servlet 3.0中,供给了AsyncContext,对异步履行的上下文供给支撑。在ServletRequest上供给了 startAsync( )办法,用于发动异步作业线程。并且AsynchContext还供给了Timeout等设置。

你能够透过AsyncContext的getRequest() 、 getResponse()办法获得Request、Response目标,此次对客户端的呼应将暂缓至调用AsyncContext的complete()办法或dispatch()停止,前者表明回应完结,后者表明将呼应调派给指定的URL 。

若要能调用ServletRequest的startAsync()运用AsyncContext,则此Servlet 有必要能援助非同步处理,假如运用@WebServlet来标明,则能够设定其asyncSupported为true 。 例如:

@WebServlet(urlPatterns = "/some.do", asyncSupported = true ) 
public class AsyncServlet extends HttpServlet 
... 

假如运用web.xml设定Servlet,则能够设定标签为true :

... 
 servlet 
 servlet-name AsyncServlet /servlet-name 
 servlet-class com.pkgname.AsyncServlet /servlet-class 
 async-supported true /async-supported 
 /servlet 
... 

假如Servlet将会异步处理,若其前端有过滤器,则过滤器亦需标明其援助异步处理,假如运用@WebFilter ,相同是能够设定其asyncSupported为true 。 例如:

@WebFilter(urlPatterns = "/some.do", asyncSupported = true ) 
public class AsyncFilter implements Filter{ 
... 

假如运用web.xml设定过滤器,则能够设定标签为true :

... 
 filter 
 filter -name AsyncFilter / filter -name 
 filter -class com.pkgname.AsyncFilter / filter -class 
 async-supported true /async-supported 
 / filter 
... 

留意: 
运用异步处理方式,web容器的恳求处理线程开释了,能够效劳其他的恳求处理。可是该Request的处理并没有完毕,在运用AsyncContext的complete或许dispatch完结后,这个request的处理才完毕。

简略的示例:
package com.ss;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
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;
// import com.cndatacom.thread.BusinessHandleThread;
 * 异步处理Servlet
 * @author 
 * asyncSupported特点默许是false,假如需求敞开支撑异步处理功用,需求设置为true
@WebServlet(name = "AsyncServlet", urlPatterns = "/AsyncServlet2", asyncSupported = true)
public class AsyncServlet2 extends HttpServlet {
 private static final long serialVersionUID = -2749650094193187229L;
 @Override
 protected void doGet(HttpServletRequest request,
 HttpServletResponse response) throws ServletException, IOException {
 response.setCharacterEncoding("utf-8");
 response.setContentType("text/html;charset=utf-8");
 PrintWriter out = response.getWriter();
 Date date = new Date(System.currentTimeMillis());
 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss Z");
 out.println("Servlet begin --" + sdf.format(date) + " br ");// 呼应输出到客户端
 // 进入异步形式,调用事务处理线程进行事务处理
 // Servlet不会被堵塞,而是直接往下履行
 // 事务处理完结后的回应由AsyncContext办理
 AsyncContext asyncContext = request.startAsync();
 BusinessWorkerThread businessHandleThread = new BusinessWorkerThread(
 asyncContext);
 Thread thread = new Thread(businessHandleThread);
 thread.start();
 //asyncContext.start(businessHandleThread);//也能够用这种办法发动异步线程
 date = new Date(System.currentTimeMillis());
 out.println("Servlet end --" + sdf.format(date) + " br ");
 out.flush();
}
------
package com.ss;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.AsyncContext;
import javax.servlet.ServletResponse;
 * 事务处理线程
 * @author 
public class BusinessWorkerThread implements Runnable {
 // 异步操作的上下文目标,经过结构办法传进来
 private AsyncContext asyncContext;
 public BusinessWorkerThread(AsyncContext asyncContext) {
 this.asyncContext = asyncContext;
 @Override
 public void run() {
 try {
 // do some work...
 Thread.sleep(8000); // 和browser的timeout时刻相关。假如browser上timeout是30s,则大于30时,网络现已断开。这是就会反常。
 ServletResponse response = asyncContext.getResponse();
 PrintWriter out = response.getWriter();
 Date date = new Date(System.currentTimeMillis());
 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss Z");
 out.println("business worker finished --"+ sdf.format(date));// 呼应输出到客户端
 // 通知发动异步处理的Servlet异步处理已完结,Servlet就会提交恳求呼应
 asyncContext.complete();
 } catch (Exception e) {
 e.printStackTrace();
}
输出: 在浏览器中,输出的内容依照后边的时刻显现在页面上。
Servlet begin --22:33:57 +0800
Servlet end --22:33:57 +0800
business worker finished --22:34:05 +0800

留意: 运用浏览器拜访,由于各个浏览器的http恳求超时设置不同,比方我的chrome是30秒。AsyncContext中对应的作业线程的持续时刻需求小于浏览器的http超时时刻。

AsyncListener

AsyncContext还能够设置一个Listener,对4个事情进行处理:

示例:

 package com.ss;
import java.io.IOException;
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;
 * Servlet implementation class AsyncServletTest
@WebServlet(asyncSupported = true, urlPatterns = { "/AsyncTest" })
public class AsyncServletTest extends HttpServlet {
 String param = "";
 private static final long serialVersionUID = 1L;
 * @see HttpServlet#HttpServlet()
 public AsyncServletTest() {
 super();
 // TODO Auto-generated constructor stub
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
 * response)
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws ServletException, IOException {
 // 1 start async
 final AsyncContext ctx = req.startAsync();
 param = ctx.getRequest().getParameter("seq");
 System.out.println("getRequest request seq: " + param);
 // 2 set the timeout
 ctx.setTimeout(0);
 // 3 add listener
 ctx.addListener(new AsyncListener() {
 @Override
 public void onTimeout(AsyncEvent arg0) throws IOException {
 System.out.println("onTimeout...");
 @Override
 public void onStartAsync(AsyncEvent arg0) throws IOException {
 System.out.println("onStartAsync...");
 @Override
 public void onError(AsyncEvent arg0) throws IOException {
 System.out.println("onError...");
 @Override
 public void onComplete(AsyncEvent arg0) throws IOException {
 System.out.println("onComplete...");
 // 4 run a thread
 ctx.start(new Runnable() {
 @Override
 public void run() {
 String seq = ctx.getRequest().getParameter("seq");
 System.out.println(" now respone: " + seq);
 int n = 0;
 try {
 // hold until receive exit
 while (!param.equals("exit")) {
 n++;
 if (n % 100000000 == 0) {
 System.out.println(seq + ": ..." + n);
 ctx.getResponse().getWriter().write(seq+" -- "+n);
 } catch (IOException e) {
 e.printStackTrace();
 ctx.complete();
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
 * response)
 protected void doPost(HttpServletRequest request,
 HttpServletResponse response) throws ServletException, IOException {
 // TODO Auto-generated method stub
 System.out.println("doPost...");
}
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表AG环亚娱乐集团立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1

    oxygenxml.oxygenITeye

    插件,生成器,代码
  • 2

    JVM参数装备大全ITeye

    信息,打印,前后
  • 3

    ThreadITeye

    先后,正常,作业
  • 4
  • 5

    vba upgradeITeye

    文件,程序,晋级
  • 6

    java 多线程ITeye

    线程,作业,内存
  • 7
  • 8

    ClassLoaderITeye

    运用,文件,办法
  • 9
  • 10

    手机号码校验合法性ITeye

    代表,必定,第二位