在Servlet 3.0
之前,Servlet
采用Thread-Per-Request
的方式处理请求,即每一次Http
请求都由某一个线程从头到尾负责处理。如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。即便是像Spring
、Struts
这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet
之上的。为了解决这样的问题,Servlet 3.0
引入了异步处理,然后在Servlet 3.1
中又引入了非阻塞IO来进一步增强异步处理的性能。
在Servlet 3.0
中,我们可以从HttpServletRequest
对象中获得一个AsyncContext
对象,该对象构成了异步处理的上下文,Request
和Response
对象都可从中获取。AsyncContext
可以从当前线程传给另外的线程,并在新的线程中完成对请求的处理并返回结果给客户端,初始线程便可以还回给容器线程池以处理更多的请求。如此,通过将请求从一个线程传给另一个线程处理的过程便构成了Servlet 3.0
中的异步处理。
演示
|
|
为了模拟长时处理过程,创建了一个LongRunningProcess
类,其run()
方法将随机地等待2秒之内的一个时间:
|
|
此时的SyncHelloServlet
将顺序地先执行LongRunningProcess
的run()
方法,然后将将HelloWorld
返回给客户端,这是一个典型的同步过程。