JAXRS异步服务

时间:2017-03-23 21:40:40

标签: asynchronous java-ee jax-rs

以下是泽西岛docs针对异步服务的示例代码:

@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();
    }
}

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

  

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

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

另一方面,异步Web请求从工作线程中解耦请求/响应对象(以及jax-rs在servlet-container部署的情况下使用servlet下面的servlet)。因此,你可以拥有10个线程,但实例却有1000个请求(继续阅读)。

  

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

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

此外,您不需要生成新线程。实际上这是一个可怕的解决方案。线程创建很昂贵。相反,您应该将runnables提交给线程池。

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

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