5

I was reading up on Async servlets 3.1

It is said that the thread that sends the request is freed up when there is lot of time consuming operations to be done for e.g. fetching long list of data from the database.

I am not able to understand the benefit here because anyways there will be a new thread allocated to process the database connection and response processing even if the initial thread that was responsible for the request is freed.

So how is Async servlet more beneficial than thread per request model that we had earlier.

4

2 回答 2

2

在这里分两部分回答:

  1. Async servlet 如何比我们之前的每个请求线程模型更有益:这种模型早已失效,几乎所有 Java 服务器都使用 NIO,它允许这些服务器使用少数线程处理数百个连接。您也可以为您的应用服务器验证这一点,您会惊喜地发现它确实使用了 NIO :)。Async Servlet 与每个线程一个请求没有任何关系。
  2. 那么为什么异步 Servlets:嗯,异步 Servlets允许完成原始请求,而无需等待异步任务完成(希望是长时间运行)。因此,远程客户端可以立即响应,如果需要,他们可以做一些其他的事情。服务器稍后可以在其中一个线程中处理异步任务。这些异步操作通常在单独的线程池中完成,用于异步操作。用于处理客户端连接的线程池用于异步操作。

更新:如果我们已经在使用 NIO 线程池,关于为什么我们需要 Async Servlets 的更多细节我确实在http://manish-m.com/?p=996 上记下了关于非阻塞 IO 的笔记。您还可以在http://manish-m.com/?p=915上查看相关帖子(尤其是此页面上的 IO Playground 部分)。

NIO 线程池用于处理多个连接请求。它利用内核的非阻塞 IO 特性,使得少量线程可以处理多个连接。

但是,从网络缓冲区读取数据的线程也会执行“用户代码”(我们在 servlet 中编写的代码)。NIO 的 servlet 容器框架处理接受客户端请求,但它不能自己处理由我们编写的“阻塞用户代码”。因此,如果我们编写一个需要 10 秒的 DB 查询,那么容器框架无法自行异步处理它。我们将通过在 servlet 中编写任何阻塞代码来阻塞原始 NIO 线程池。因此,我们需要显式编写任何我们认为可能会阻塞容器的请求线程的内容,作为 Java EE 中的异步 servlet。

同样,当我们使用 Netty、MINA 等其他 NIO 框架时,我们需要注意确保代码“不会”阻塞处理网络连接的 NIO 线程。这通常是通过将这些长时间运行的任务卸载到另一个线程池来实现的(这是容器在您编写异步 servlet 时所做的事情)。

于 2014-11-29T20:44:29.957 回答
0

只有这么多线程可用于服务 HTTP 请求。这些来自 HTTP 线程池,可通过您的应用程序服务器配置机制(例如 Glassfish 的管理 UI)进行配置。如果您的 servlet 执行长时间运行的操作,这些请求线程将被占用。一旦所有池化的请求线程都被占用,在一个被释放之前,将无法处理更多的请求。

使用异步 servlet,请求线程将返回到池中,而不是在非异步情况下被长时间运行的同步操作阻塞。

于 2014-11-29T18:10:29.793 回答