servlet3.0 异步处理

 package com.yc.servlet;


import java.io.IOException;
import java.util.concurrent.ThreadPoolExecutor;


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;


/**
 * 源辰信息
 * 异步访问方式
 * 在Servlet3.0中,提供了AsyncContext,对异步执行的上下文提供支持。在ServletRequest上提供了 startAsync( )方法,
 * 用于启动异步工作线程。而且AsynchContext还提供了Timeout等设置。
 * 你可以透过AsyncContext的getRequest() 、 getResponse()方法取得Request、Response对象,
 * 此时对客户端的响应将暂缓至调用AsyncContext的complete()方法或dispatch()为止,前者表示回应完成,后者表示将响应调派给指定的URL 。
 * 若要能调用ServletRequest的startAsync()使用AsyncContext,则此Servlet 必须能支援非同步处理,如果使用@WebServlet来标注,
 * 则可以设定其asyncSupported为true 。
 * 注意:使用异步处理方式,web容器的请求处理线程释放了,可以服务其他的请求处理。
 * 但是该Request的处理并没有结束,在使用AsyncContext的complete或者dispatch完成后,这个request的处理才结束。
 * web.xml的配置
 * <servlet>   
 * <servlet-name>AsyncServlet</servlet-name>   
 * <servlet-class>com.yc.servlet.AsyncServlet</servlet-class>   
 * <async-supported>true</async-supported>   
 * </servlet>   
 * @author navy
 * 2017年4月28日
 */
@WebServlet(urlPatterns="/asyncServlet",asyncSupported=true)
public class AsyncServlet extends HttpServlet {
private static final long serialVersionUID = 1L;


public AsyncServlet() {
super();
}


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");


long startTime = System.currentTimeMillis();
System.out.println("当前线程名:"+ Thread.currentThread().getName() 
+ " 线程ID:" + Thread.currentThread().getId());


//获取异步执行上下文对象
AsyncContext asyncCtx = request.startAsync();


//给异步执行上下文对象添加监听事件
asyncCtx.addListener(new AppAsyncListener());
asyncCtx.setTimeout(2000000); //异步请求超市时间


//获取请求线程池
ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext().getAttribute("executor");
executor.execute(new AsyncRequestProcessor(asyncCtx, 10000)); //使用异步方式处理请求

//非线程池方式
//new Thread(new AsyncRequestProcessor(asyncCtx, 10000)).start();


long endTime = System.currentTimeMillis();
System.out.println("当前线程名:"+ Thread.currentThread().getName() 
+ " 线程ID:" + Thread.currentThread().getId()
+ " 程序运行时长 " + (endTime - startTime) + " 毫秒 ");
}
}


 package com.yc.servlet;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;


/**
 * 源辰信息
 * 应用程序启动时创建一个线程池,用来给servlet的异步请求提供线程
 * @author navy
 * 2017年4月28日
 */
@WebListener
public class ApplicationListener implements ServletContextListener {
/**
* corePoolSize: 线程池维护线程的最少数量
* maximumPoolSize:线程池维护线程的最大数量
* keepAliveTime: 线程池维护线程所允许的空闲时间
* unit: 线程池维护线程所允许的空闲时间的单位
* workQueue: 线程池所使用的缓冲队列
* handler: 线程池对拒绝任务的处理策略
*/
    @Override
    public void contextInitialized(ServletContextEvent sce) {
    System.out.println("初始化线程池开始...");
        ThreadPoolExecutor executor = new ThreadPoolExecutor(50,100,50000L,
                TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(5000));
        sce.getServletContext().setAttribute("executor", executor);
        System.out.println("初始化线程池完毕...");
    }


    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) sce.getServletContext().getAttribute("executor");
        executor.shutdown();
    }
}


 package com.yc.servlet;


import java.io.IOException;
import java.io.PrintWriter;


import javax.servlet.AsyncContext;
import javax.servlet.ServletRequest;


/**
 * 源辰信息
 * 异步servlet处理长时间任务的线程
 * @author navy
 * 2017年4月28日
 */
public class AsyncRequestProcessor implements Runnable {
    private AsyncContext asyncContext;
    private int milliseconds;


    public AsyncRequestProcessor() {


    }


    public AsyncRequestProcessor(AsyncContext asyncContext, int milliseconds) {
        this.asyncContext = asyncContext;
        this.milliseconds = milliseconds;
    }


    @Override
    public void run() {
    ServletRequest request=asyncContext.getRequest(); //从异步请求上下文对象中获取请求对象
    String uname=request.getParameter("uname"); //获取请求中的参数
System.out.println(uname);
        System.out.println(" 异步请求方式 :"+ asyncContext.getRequest().isAsyncSupported());
        
        try {
Thread.sleep(milliseconds); //休眠10秒
} catch (InterruptedException e1) {
e1.printStackTrace();
}
        
        try {
            PrintWriter out = asyncContext.getResponse().getWriter();
    out.write("请求处理10秒后...");
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        asyncContext.complete(); //完成异步请求
        //asyncContext.dispatch(""); //完成异步请求,跳转到另外一个页面
    }
}


 package com.yc.servlet;


import java.io.IOException;
import java.io.PrintWriter;


import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;


/**
 * 源辰信息
 * 异步监听器,监听异步servlet的过程
 * @author navy
 * 2017年4月28日
 */
@WebListener
public class AppAsyncListener implements AsyncListener {
    @Override
    public void onComplete(AsyncEvent event) throws IOException {
        System.out.println("异步servlet处理完成...");
    }


    @Override
    public void onTimeout(AsyncEvent event) throws IOException {
        ServletResponse response = event.getAsyncContext().getResponse();
        PrintWriter out = response.getWriter();
        out.write("异步servlet处理超时...");
        out.flush();
        out.close();


    }


    @Override
    public void onError(AsyncEvent event) throws IOException {
        ServletResponse response = event.getAsyncContext().getResponse();
        PrintWriter out = response.getWriter();
        out.write("异步servlet处理出错...");
        out.flush();
        out.close();
    }


    @Override
    public void onStartAsync(AsyncEvent event) throws IOException {
        System.out.println("异步servlet处理开始...");
    }
}


package com.yc.servlet;


import java.io.IOException;
import java.io.PrintWriter;


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 源辰信息
 * 同步访问方式
 * @author navy
 * 2017年4月28日
 */
@WebServlet(urlPatterns="/syncServlet")
public class SyncServlet extends HttpServlet {
private static final long serialVersionUID = 1L;


public SyncServlet() {
super();
}


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");


//获取当前系统时间
long startTime = System.currentTimeMillis();
System.out.println("当前线程名:"+ Thread.currentThread().getName() 
+ " 线程ID:" + Thread.currentThread().getId());


String uname=request.getParameter("uname");
System.out.println(uname);






try {
Thread.sleep(10000);//休眠10秒
} catch (InterruptedException e) {
e.printStackTrace();



PrintWriter out = response.getWriter();
long endTime = System.currentTimeMillis();
out.write("请求处理10秒后...");
System.out.println("当前线程名:"+ Thread.currentThread().getName() 
+ " 线程ID:" + Thread.currentThread().getId()
+ " 程序运行时长 " + (endTime - startTime) + " 毫秒 ");
out.flush();
out.close();
}


}




<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>servlet3.0</title>
</head>
<body>
<h1>同步请求</h1>
<form action="syncServlet" method="post">
<label>用户名:</label><input type="text" name="uname" value="源辰"/>
<input type="submit" value="提交" />
</form>
<h1>异步请求</h1>
<form action="asyncServlet" method="post">
<label>用户名:</label><input type="text" name="uname" value="源辰"/>
<input type="submit" value="提交" />
</form>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值