个人理解:
异步Servlet工作方式在主线程基础之上再新开一个子线程来处理比较耗时的任务,两个线程共用一个socket连接,所以在连接的关闭上需小心。
异步Servlet代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package me.ypqiao.javaee6sample.listener;
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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* @author ypqiao
*/
@WebServlet(name = "AsynServlet", urlPatterns = {"/AsynServlet"},
asyncSupported = true)
public class AsynServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println(" work1 completed <br/>");
// get and config an instance of AsyncContext
AsyncContext ctx = request.startAsync();
ctx.setTimeout(2000);
ctx.addListener( new AsyncContextListener() );
// start the asynccontext to do ayncwork
ctx.start( new AsyncTask(ctx));
out.println(" work3 completed <br/>");
} finally {
out.flush();
}
}
}
class AsyncTask implements Runnable {
private static Log log = LogFactory.getLog(AsyncTask.class);
private AsyncContext context;
public AsyncTask(AsyncContext context){
this.context = context;
}
@Override
public void run() {
log.info(" start to do a long-time work ");
try {
Thread.sleep(2000);
context.getResponse().getWriter().print(" work2 completed <br/>");
//throw new RuntimeException(" exception test ");
}
catch( Exception e ){
log.error(e.getMessage(),e);
}
finally{
context.complete();
}
}
}
class AsyncContextListener implements AsyncListener{
private static Log log = LogFactory.getLog(AsyncContextListener.class);
@Override
public void onComplete(AsyncEvent event) throws IOException {
log.info(" the asyn context has been completed ");
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
log.warn(" the asyn context has been timeout ");
}
@Override
public void onError(AsyncEvent event) throws IOException {
log.error(" the asyn context has error ",event.getThrowable());
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
log.debug(" the asyn context has started ",event.getThrowable());
}
}