我对Servlet 3.0规范中引入的异步功能感到困惑
来自Oracle网站(http://docs.oracle.com/javaee/7/tutorial/doc/servlets012.htm):
要创建可伸缩的Web应用程序,必须确保没有线程 与请求相关联的是空闲,因此容器可以使用 他们处理新的请求。
有两种常见的情况,其中一个线程与一个相关联 请求可以闲着。
1-线程需要在构建响应之前等待资源变为可用或处理数据。例如,一个应用程序 可能需要查询数据库或从远程Web服务访问数据 在生成响应之前。
2-线程需要在生成响应之前等待事件。例如,应用程序可能必须等待JMS 消息,来自其他客户端的新信息或可用的新数据 生成响应之前的队列。
第一个项目发生了很多(几乎总是,我们总是查询db或调用远程Web服务来获取一些数据)。调用外部资源总是会耗费一些时间。
这是否意味着我们应该始终对所有servelt和过滤器使用servelt异步功能? 我也可以这样问,如果我写了所有的servelts和过滤异步,我会失去任何东西(性能)吗?!
如果以上是正确的,我们所有servlet的骨架将是:
public class Work implements ServletContextListener {
private static final BlockingQueue queue = new LinkedBlockingQueue();
private volatile Thread thread;
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
ServiceFecade.doBusiness();
AsyncContext context;
while ((context = queue.poll()) != null) {
try {
ServletResponse response = context.getResponse();
PrintWriter out = response.getWriter();
out.printf("Bussiness done");
out.flush();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
} finally {
context.complete();
}
}
} catch (InterruptedException e) {
return;
}
}
}
});
thread.start();
}
public static void add(AsyncContext c) {
queue.add(c);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
thread.interrupt();
}
}