【问题标题】:JAXRS Asynchronous ServicesJAXRS 异步服务
【发布时间】:2017-08-16 16:27:21
【问题描述】:

这是来自 Jersey 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();
    }
}

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

【问题讨论】:

    标签: asynchronous jakarta-ee jax-rs


    【解决方案1】:

    没有必要像这样创建一个新线程。如果您在 JavaEE 环境中,您可以简单地在您的方法中放置一个 @Asynchronous 注解:

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

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

    【讨论】:

    • 没有那么简单。首先,该资源必须标记为 EJB。第二:你需要一个完整的配置文件服务器,因为网络配置文件不支持@Asynchronous
    • 是的,我忘了提到 AsyncResource 必须是 EJB。您还可以将异步方法放在单独的 EJB 中。
    【解决方案2】:

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

    其实你可以配置容器工作线程的数量,但是你还是受制于它们。如果你有 10 个容器线程,那么你可以同时处理 10 个请求。如果你有 100 个线程,那么你可以同时有 100 个请求

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

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

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

    您也不需要生成一个新线程。实际上,这是一个可怕的解决方案。线程创建是昂贵的。相反,您应该将可运行文件提交到线程池。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多