JAX-RS 客户机线程安全吗

2022-09-01 16:16:29

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

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


答案 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

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


答案 2

请注意:虽然这是公认的答案,但这是特定于实现的,对于泽西岛1客户来说是正确的。为此,您绝对应该共享单个实例。为每个请求创建一个客户端是一个巨大的性能开销

JavaDoc主要已经回答了你的问题 - 是的,它是线程安全的,你可以而且应该重用它。重用它可能会有一个性能问题,也就是说,如果你为每个HTTP请求创建一个客户端,你做出的性能会很糟糕。