您的位置:首页 > 编程语言 > Java开发

JavaEE Async 异步支持

2018-03-26 15:34 309 查看

前言

Async技术是Servlet3.0 之后添加的,用于处理异步请求。在此之前,大多为同步请求,客户端向服务器提交请求,假设请求很耗时,那么按照之前同步的处理办法,servlet在接收到这个请求之后,会调用去处理这个耗时操作,如果这个耗时操作长时间没有返回,那么就造成了服务器的阻塞,服务器资源得不到有效利用,这样的结果显然对于服务器的高并发是非常不利的。

服务器可以异步执行,在等待长时间的过程完成期间,控制容器执行其他任务,当耗时操作完成返回后,再调用资源处理这个返回请求。

使用Async的步骤

启用async

异步行为需要在Servlet中显式启用 ,其方法有两种:

添加@WebServlet的asyncSupported属性实现

@WebServlet(urlPatterns = "/async", asyncSupported = true)


web.xml文件中实现

<servlet>
<servlet-name>AsyncServlet</servlet-name>
<servlet-class>com.dimple.servlet.AsyncServlet</servlet-class>
<async-supported>true</async-supported> <!--设置启用Async-->
</servlet>


在Servlet中开启async

@WebServlet(name = "AsyncServlet", urlPatterns = "/async",asyncSupported = true)
public class AsyncServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
//输出Servlet开始的时候的系统时间
out.println("Servlet is starting:"+new Date());
//创建AsyncContext,开始异步调用
AsyncContext asyncContext=request.startAsync();
//设置超时时长,单位为毫秒
asyncContext.setTimeout(60*1000);
//启动异步调用的线程
asyncContext.start(new MyTask(asyncContext));
//输出Servlet结束的时间
out.println("Servlet is ending :"+new Date());
}
}


MyTask内容:

public class MyTask implements Runnable {
AsyncContext context;

public MyTask(AsyncContext context) {
this.context = context;
}

/**
* 此处单开一个线程进行耗时操作,为了模拟耗时操作,这里先让线程Sleep5秒。
*/
@Override
public void run() {
try {
Thread.sleep(5*1000);
context.getResponse().getWriter().print("async is ending : "+new Date());
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}


执行结果如下:



注意:这是采用IDEA开发的,可能采用Eclipse的小伙伴的开发的和我这边的url不一样。

AsyncListener 异步监听器

为了更加清晰的看到异步操作的各种细节,可以借助异步监听器实现。

异步监听器需要实现AsyncListener接口,该接口需要实现如下方法:

@Override
public void onComplete(AsyncEvent asyncEvent) throws IOException {
//当异步调用完成后被调用
}

@Override
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
//超时被调用
}

@Override
public void onError(AsyncEvent asyncEvent) throws IOException {
//出现错误的时候被调用
}

@Override
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
//启动Async的时候被调用
}


添加监听
4000
器的方法:

asyncContext.addListener(new MyAsyncListener);


总结

使用Servlet3.0的Async异步支持,步骤总结如下:

首先先声明异步支持(web.xml或者注解@webServlet)

在相应的Servlet中获取AsyncContext实例。一般采用
request.startAsync();
该方法发挥一个AsyncContext对象。

设置超时
context.setTimeout();


启动线程
context.start(Runable runable);


在相应的实现Runable接口的方法里进行耗时操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaEE JavaWeb Async 异步