我不懂servlet 3.0 API中的异步支持

Ism*_*ush 33 ajax servlets java-ee

我来自Java SE背景,我做了一些servlet教程并阅读了Head First JSP和servlet.我正在阅读有关Async支持的JavaWorld.com文章,但我不太明白.

什么是异步是简单的?Ajax和Servlet Async有什么区别?

PS我有一个带有ajax的PHP背景,我知道这个概念,但我还没有用java试过

Arj*_*jms 83

在传统的Servlet模型中,通常情况是1个请求对应于1个线程.

这些线程通常来自由Servlet容器管理的池.Servlet容器只能处理新请求,只要它在此池中有空闲线程即可.只要您自己的代码忙于处理请求,该线程就不是免费的.

在某些情况下,打破这个模型可能是值得的.发生的事情是请求通过这样的Servlet容器管理线程到达Servlet,然后您的代码要求异步执行.然后,您可以从Servlet请求返回,并释放容器线程.

与同步请求处理相反,这不会提交任何响应,也不会关闭连接.相反,你可以用手异步上下文切换到另一个线程池,它可以把它捡起来,而当某个线程可以自由地处理它,它的服务,将能够写入响应.

一个例子:

@WebServlet(urlPatterns = "/somepath", asyncSupported = true)
public class AsyncServlet extends HttpServlet {

    @EJB
    private AsyncBean asyncBean;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();

        // The following line will not block and return immediately
        asyncBean.doAsyncStuff(asyncContext);

    } // Shortly after this method has ended, thread will be returned to pool
}
Run Code Online (Sandbox Code Playgroud)

随着AsyncBean实施:

@Stateless
public class AsyncBean {

    @Asynchronous
    public void doAsyncStuff(AsyncContext asyncContext) throws IOException {
        asyncContext.getResponse().getWriter().write("test");
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,从AsyncServlet#doGet()方法返回后不久,Servlet线程将返回到池中.用于执行的"请求"(任务)AsyncBean#doAsyncStuff()将被放入队列中以供EJB线程池获取.

你为什么以及什么时候使用它的答案并不那么简单.如果你只想保留线程,那么在上面的例子中,你将从一个线程池中为另一个线程池交换一个线程(在这种情况下是Servlet池与EJB异步池),并且净效益不会那么多.你也可以给你的Servlet线程池一个额外的线程.

在更高级的场景中,您可以对请求进行更细粒度的管理; 将它们分成多个任务,并为这些任务提供线程池服务.例如,假设有10个线程处理的10MB文件的100个下载请求,循环法给每个请求发送100KB的时间.

另一个应用程序是需要等待来自外部系统的数据的请求,并且该外部系统能够发送可以中继回请求者的消息.即数据库调用在这里没有意义,因为无论如何你还需要另一个线程来等待响应.然后你会再次为另一个线程换一个线程.但是,如果您需要等待收到传入的电子邮件,那么一个线程可以等待任何电子邮件并将其转发给任何已暂停的请求.

  • 谢谢!我在网上搜索了这个主题,但几乎所有我发现的例子只交换了另一个线程,不讨论这个问题!我认为大多数人只是使用异步处理(愚蠢)而不知道他们正在做什么/为什么他们这样做. (8认同)
  • 我不完全理解如何将一个线程从一个池移动到另一个池可以从可伸缩性的角度来看有所不同.我看到了将服务器侦听器线程返回到池的重点,但我真的不知道这是否可以大大提高应用程序的可伸缩性. (4认同)
  • 交换线程对可伸缩性没有帮助,但请参阅下载示例.一些线程可能能够提供许多异步连接.如果请求可以分解为几个可以排队的任务,那么考虑这种模式可能是值得的.否则,确实没有太多预期的好处. (3认同)
  • 非常感谢Arjan,第一段非常清晰易懂. (2认同)