Servlet 3.0 以前,一个普通 Servlet 的主要工做流程大体以下:html
首先,Servlet 接收到请求以后,可能须要对请求携带的数据进行一些预处理;java
接着,调用业务接口的某些方法,以完成业务处理;mysql
最后,根据处理的结果提交响应,Servlet 线程结束。web
其中第二步的业务处理一般是最耗时的,这主要体如今数据库操做,以及其它的跨网络调用等,在此过程当中,Servlet 线程一直处于阻塞状态,直到业务方法执行完毕。在处理业务的过程当中,Servlet 资源一直被占用而得不到释放,对于并发较大的应用,这有可能形成性能的瓶颈。即便在业务类中开启一个线程,线程处理后的结果是没法返回给页面的,由于servlet执行完毕后,response就关闭了,没法将后台更新数据即时更新到页面端sql
注:servlet3.0 之前一般是采用私有解决方案来提早结束 Servlet 线程,并及时释放资源。数据库
Servlet 3.0 针对这个问题作了开创性的工做,如今经过使用 Servlet 3.0 的异步处理支持,以前的 Servlet 处理流程能够调整为以下的过程:网络
首先,Servlet 接收到请求以后,可能首先须要对请求携带的数据进行一些预处理;并发
接着,Servlet 线程将请求转交给一个异步线程来执行业务处理,线程自己返回至容器,此时 Servlet 尚未生成响应数据,异步线程处理完业务之后,能够直接生成响应数据(异步线程拥有 ServletRequest 和 ServletResponse 对象的引用),或者将请求继续转发给其它 Servlet。异步
如此一来, Servlet 线程再也不是一直处于阻塞状态以等待业务逻辑的处理,而是启动异步线程以后能够当即返回。async
一、异步处理特性能够应用于 Servlet 和过滤器两种组件,因为异步处理的工做模式和普通工做模式在实现上有着本质的区别,所以默认状况下,Servlet 和过滤器并无开启异步处理特性,若是但愿使用该特性,则必须按照以下的方式启用:
<servlet> <servlet-name>DemoServlet</servlet-name> <servlet-class>footmark.servlet.Demo Servlet</servlet-class> <async-supported>true</async-supported> </servlet>
@WebFilter(urlPatterns = "/demo",asyncSupported = true) public class DemoFilter implements Filter{...}
二、Servlet 3.0 还为异步处理提供了一个监听器,使用 AsyncListener 接口表示。它能够监控以下四种事件:
AsyncContext ctx = req.startAsync(); ctx.addListener(new AsyncListener() { public void onComplete(AsyncEvent asyncEvent) throws IOException { // 作一些清理工做或者其余 } ... });