JAXRS 异步服务



下面是来自 Jersey 异步服务文档的示例代码:

@Path("/resource")
public class AsyncResource {
@GET
public void asyncGet(@Suspended final AsyncResponse asyncResponse) {
new Thread(new Runnable() {
@Override
public void run() {
String result = veryExpensiveOperation();
asyncResponse.resume(result);
}
private String veryExpensiveOperation() {
// ... very expensive operation
}
}).start();
}
}

考虑到容器已经负责将连接处理线程释放回池并将请求处理传递给工作线程,我想知道为什么我们仍然需要以编程方式生成一个新线程?这不应该只是容器配置(设置工作线程数)的问题吗?

没有必要像这样旋转一个新线程。如果您处于 JavaEE 环境中,则只需在方法中放置一个@Asynchronous注释:

@GET
@Asynchronous
public void asyncGet(@Suspended final AsyncResponse asyncResponse) {
String result = veryExpensiveOperation();
asyncResponse.resume(result);
}

我需要扩展线程池你也可以看看ManagedExecutorService

这不应该只是容器配置(设置工作线程数)的问题吗?

实际上,您可以配置容器工作线程的数量,但您仍然受它们的约束。如果您有 10 个容器线程,则可以同时处理 10 个请求。如果您有 100 个线程,则可以同时有 100 个请求

另一方面,异步 Web 请求将请求/响应对象(jax-rs 在 servlet 容器部署的情况下在下面使用 servlet)与工作线程分离。因此,您可以有 10 个线程,但例如 1000 个请求(继续阅读)。

我想知道为什么我们仍然需要以编程方式生成一个新线程?

如果您仍然要在同一线程中处理请求,那么将请求与线程分离是没有意义的,因为在这种情况下,异步/同步请求之间绝对没有区别。

此外,您还需要生成一个新线程。实际上,这是一个可怕的解决方案。线程创建成本很高。相反,您应该将可运行项提交到线程池。

那么异步请求有什么用呢?它们适用于需要大量时间才能完成的操作。做以下实验。

  1. 将 tomcat(或您选择的服务器)配置为使用 10 个线程的池。
  2. 让你的资源只睡 10 秒。
  3. 尽可能多地请求它。
  4. 使您的资源异步,而不是在其中等待,将仅等待 10 秒的可运行对象提交到线程池 ->您现在可以发出多少请求?

最新更新