【问题标题】:Is JAX-RS Client Thread SafeJAX-RS 客户端线程安全吗
【发布时间】:2014-07-11 15:01:39
【问题描述】:

在 Java EE7 中,JAX-RS 客户端 API 提供了用于访问任何 REST 资源的高级 API。根据文档,“客户端是管理客户端通信基础设施的重量级对象。初始化和处置客户端实例可能是一项相当昂贵的操作。因此建议只构建少量应用程序中的客户端实例数。"

为了避免频繁创建客户端,我将缓存客户端实例并重用它。客户端实例线程是否安全,因为它可以被并发线程使用? 如果我只创建客户端实例并将其重用于所有请求,是否存在任何性能问题?

【问题讨论】:

  • 很好的问题和 JAX-RS 规范中明显的遗漏。我有兴趣获得规范负责人对此的意见并提交建议以在规范中更明确地说明这一点。要么它是线程安全的,在这种情况下,您的应用程序中只需要一个实例。或者不是,每个线程至少需要一个实例。但是模糊的“因此建议在应用程序中只构建少量的客户端实例”这一行绝对没有信息价值。

标签: java multithreading rest jax-rs


【解决方案1】:

我不确定,但我认为这是一个特定于实现的决定。

我在 JAX-RS 2.0 规范和 Javadoc 中都找不到任何授予 javax.ws.rs.client.Client 是线程安全的内容。但在 Resteasy(JAX-RS 的实现者)文档中,我发现:

HttpClient 做出并被 Resteasy 采用的一个默认决定是 使用 org.apache.http.impl.conn.SingleClientConnManager,其中 在任何给定时间管理单个套接字并支持使用 一个或多个调用是从一个单一的串行进行的情况 线。对于多线程应用程序,SingleClientConnManager 可能是 取而代之 org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager:

ClientConnectionManager cm = new ThreadSafeClientConnManager();
HttpClient httpClient = new DefaultHttpClient(cm);
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);

来源:http://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html/RESTEasy_Client_Framework.html#transport_layer

根据这些信息,我猜您的问题的答案很可能是“否”。

【讨论】:

  • 您现在可以:new ResteasyClientBuilder().connectionPoolSize(10)... 创建线程安全的 ResteasyClient
  • 在这里查看我的答案stackoverflow.com/a/38343094/345718 以获得轻松的解决方案。
  • This 线程相关
【解决方案2】:

请注意:尽管这是公认的答案,但这是特定于实现的,并且对于 Jersey 1 客户端是正确的。为此,您绝对应该共享一个实例。为每个请求创建一个客户端是一个巨大的性能开销

JavaDoc 主要已经回答了您的问题 - 是的,它是线程安全的,您可以并且应该重用它。 重用它可能会导致性能问题,即如果您为每个 HTTP 请求创建一个客户端,您的性能将非常糟糕。

【讨论】:

  • JavaDoc 在哪里说的? docs.oracle.com/javaee/7/api/javax/ws/rs/client/Client.html 我同意另一个答案(stackoverflow.com/a/27427911/57217),这似乎是一个特定于实现的主题。当然你不应该为每个请求创建一个新的客户端,但是从多个线程中使用它也是不安全的。
  • 我说的是“大部分”——“因此建议只构建少量的客户端实例”。尽管您说得对,它将是特定于实现的,但我可以保证使用 Jersey 客户端可以安全地从多个线程中使用。我的后端系统容量很大!
  • 这取决于实现。例如:cxf.apache.org/docs/…
  • 这不应该是公认的答案。它鼓励你推断不存在的东西。在 Java 领域,永远不要假设任何东西都是线程安全的——必须明确说明。 SimpleDateFormat 就是一个很好的例子。我没有从文档中推断它是线程安全的,而是它们的创建成本很高,因此请谨慎使用。
  • 我无法删除答案,因为它是已接受的答案
猜你喜欢
  • 2011-05-22
  • 2012-05-22
  • 2019-03-20
  • 2016-12-06
  • 1970-01-01
  • 2023-04-04
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多