[Java EE 7] Servlet 异步支持
程序员文章站
2022-04-25 10:03:44
...
服务器资源非常宝贵,因此需要节省开销。比如 servlet 需要等待数据库查询数据、等待生成报表、等待读取文件系统数据,等等。这些“长时间处理”将会完全地占用容器线程,于是,这些被占用的线程将无法再接收其它的请求,这对于珍贵的服务器资源来说,并没有做到最佳优化。
这些需要“长时间处理”的地方我们可以使用异步处理来进行优化,servlet 接收到请求后,开启新的线程来进行长时间处理,并将容器线程返还给容器,这样容器线程就可以继续接收其它请求,等长时间运行的线程执行完成后,再使用和请求相同的容器线程响应到客户端。
异步行为需要显示地在 servlet 中声明,可以在 @WebServlet 中添加 asyncSupported 属性:
也可以在 web.xml 中设置 <async-supported> 元素的值为 true,也可以使用代码的方式 ServletRegistration.setAsyncSupported(true)。
开始异步处理之前,需要调用 request 的 startAsync 方法来将容器线程分离。这个方法将会返回 AsyncContext 对象,这个对象是异步处理上下文,你可以显示地调用 AsyncContext.complete 来结束异步处理。
下面看看异步处理的例子:
这个服务可以在 doGet 中进行异步处理:
在上面的代码中,request 开启了异步模式。AsyncListener 用于监听请求是否完成、超时或出错。MyAsyncService 作为长时间运行操作开启了一个新的线程,并且调用了 AsyncContext.complete 方法发出请求已完成的信号。
请求可以从异步的 servlet 发送到同步的 servlet,但是反过来却是非法的。
异步处理在 servlet filter 中也适用。
文章来源:http://www.aptusource.org/2014/04/java-ee-7-asynchronous-support/
这些需要“长时间处理”的地方我们可以使用异步处理来进行优化,servlet 接收到请求后,开启新的线程来进行长时间处理,并将容器线程返还给容器,这样容器线程就可以继续接收其它请求,等长时间运行的线程执行完成后,再使用和请求相同的容器线程响应到客户端。
异步行为需要显示地在 servlet 中声明,可以在 @WebServlet 中添加 asyncSupported 属性:
@WebServlet(urlPatterns="/async", asyncSupported=true) public class MyAsyncServlet extends HttpServlet { //. . . }
也可以在 web.xml 中设置 <async-supported> 元素的值为 true,也可以使用代码的方式 ServletRegistration.setAsyncSupported(true)。
开始异步处理之前,需要调用 request 的 startAsync 方法来将容器线程分离。这个方法将会返回 AsyncContext 对象,这个对象是异步处理上下文,你可以显示地调用 AsyncContext.complete 来结束异步处理。
下面看看异步处理的例子:
class MyAsyncService implements Runnable { AsyncContext ac; public MyAsyncService(AsyncContext ac) { this.ac = ac; } @Override public void run() { //. . . ac.complete(); } }
这个服务可以在 doGet 中进行异步处理:
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { AsyncContext ac = request.startAsync(); ac.addListener(new AsyncListener() { public void onComplete(AsyncEvent event) throws IOException { //. . . } public void onTimeout(AsyncEvent event) throws IOException { //. . . } //. . . }); ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); executor.execute(new MyAsyncService(ac)); }
在上面的代码中,request 开启了异步模式。AsyncListener 用于监听请求是否完成、超时或出错。MyAsyncService 作为长时间运行操作开启了一个新的线程,并且调用了 AsyncContext.complete 方法发出请求已完成的信号。
请求可以从异步的 servlet 发送到同步的 servlet,但是反过来却是非法的。
异步处理在 servlet filter 中也适用。
文章来源:http://www.aptusource.org/2014/04/java-ee-7-asynchronous-support/