jersey ws 2.0 @suspended AsyncResponse,它有什么作用?

jersey ws 2.0 @suspended AsyncResponse, what does it do?

我正在分析一些 jersey 2.0 代码,我对以下方法的工作原理有疑问:

@Stateless
  @Path("/mycoolstuff")
  public class MyEjbResource {
    …
    @GET
    @Asynchronous //does this mean the method executes on child thread ?
    public void longRunningOperation(@Suspended AsyncResponse ar) {
      final String result = executeLongRunningOperation();
      ar.resume(result);
    }

    private String executeLongRunningOperation() { … }
  }

假设我在网络浏览器中输入 www.mysite/mycoolstuff 这将执行该方法,但我不理解 asyncResponse 用于 @Asynchronous 注释的内容。从浏览器我怎么会注意到它的异步?删除注释有什么区别?还有阅读 documentation 后暂停的注释我不清楚它的目的。

@Asynchronous 注释只是告诉程序在新线程上执行此方法吗?这是做 "new Thread(.....)" 的便捷方法吗?

更新:这个注解解除了挂在请求处理线程上的服务器。吞吐量可以更好。反正来自官方docs:

Request processing on the server works by default in a synchronous processing mode, which means that a client connection of a request is processed in a single I/O container thread. Once the thread processing the request returns to the I/O container, the container can safely assume that the request processing is finished and that the client connection can be safely released including all the resources associated with the connection. This model is typically sufficient for processing of requests for which the processing resource method execution takes a relatively short time. However, in cases where a resource method execution is known to take a long time to compute the result, server-side asynchronous processing model should be used. In this model, the association between a request processing thread and client connection is broken. I/O container that handles incoming request may no longer assume that a client connection can be safely closed when a request processing thread returns. Instead a facility for explicitly suspending, resuming and closing client connections needs to be exposed. Note that the use of server-side asynchronous processing model will not improve the request processing time perceived by the client. It will however increase the throughput of the server, by releasing the initial request processing thread back to the I/O container while the request may still be waiting in a queue for processing or the processing may still be running on another dedicated thread. The released I/O container thread can be used to accept and process new incoming request connections.

@suspend 注释使调用者实际上等待您完成工作。假设您在另一个线程上有很多工作要做。当你使用 jersey @suspend 时,调用者只是坐在那里等待(所以在网络浏览器上他们只会看到一个微调器)直到你的 AsyncResponse 对象 returns 数据到它。

想象一下,您必须执行一个非常长的操作,并且您想在另一个线程(或多个线程)上执行它。现在我们可以让用户等到我们完成。不要忘记在 jersey 中,您需要在 web.xml 的 jersey servlet 定义中添加“true”才能使其正常工作。

@Suspended 如果你用过它就更明确了,否则它和使用没有任何区别 it.let 谈论它的好处。

  • @Suspended 将 pause/Suspend 当前线程直到它得到响应,默认情况下 #NO_TIMEOUT 没有暂停超时设置。所以这并不意味着您的请求响应线程可以免费供其他人使用。
  • 现在假设您希望您的服务在某个特定时间做出响应,但是您从资源调用的方法不能保证响应时间,那么您将如何管理您的服务响应 time.At可以使用 @Suspended 为您的服务设置暂停超时,甚至可以在超时时提供回退响应。

下面是一些设置suspend/pause超时的代码示例

public void longRunningOperation(@Suspended AsyncResponse ar) {
 *      ar.setTimeoutHandler(customHandler);
 *      ar.setTimeout(10, TimeUnit.SECONDS);
 *      final String result = executeLongRunningOperation();
 *      ar.resume(result);
 *    }

for more details refer this

在资源方法的 AsyncResponse 参数之前添加 @Suspended 注释,以告诉底层 Web 服务器不要期望此线程 return 对远程调用者的响应:

@POST
public void asyncPost(@Suspended final AsyncResponse ar, ... <args>) {
    someAsyncMethodInYourServer(<args>, new AsyncMethodCallback() {
        @Override
        void completed(<results>) {
            ar.complete(Response.ok(<results>).build());
        }

        @Override
        void failed(Throwable t) {
            ar.failed(t);
        }
    }
}

相反,AsyncResponse 对象由调用回调对象上的完成或失败的线程使用 return 'ok' 或向客户端抛出错误。

考虑将此类异步资源与异步球衣客户端结合使用。如果您尝试实现一个公开基本异步 api 的 ReST 服务,这些模式允许您通过 ReST 接口投射异步 api。

我们不创建异步接口,因为我们有一个进程需要很长时间(几分钟或几小时)到 运行,而是因为我们不希望我们的线程永远休眠 - 我们发送请求并注册一个回调处理程序,以便在结果准备好后调用 - 从几毫秒到几秒后 - 在同步接口中,调用线程将在此期间休眠,而不是做一些有用的事情。有史以来最快的 Web 服务器之一是单线程和完全异步的。该线程从不休眠,并且因为只有一个线程,所以在幕后(至少在该进程内)没有上下文切换。