问题描述
根据文档,
好的,我正在尝试在一个静态变量中缓存Client本身和WebTarget实例,在多线程环境中调用someMethod(): / p>
Ok, I'm trying to cache Client itself and WebTarget instances in a static variable, the someMethod() is invoked in multi-threaded environment:
private static Client client = ClientBuilder.newClient();
private static WebTarget webTarget = client.target("someBaseUrl");
...
public static String someMethod(String arg1, String arg2)
{
WebTarget target = entrTarget.queryParam("arg1", arg1).queryParam("arg2", arg2);
Response response = target.request().get();
final String result = response.readEntity(String.class);
response.close();
return result;
}
但有时(并非总是)我得到一个例外:
But sometimes (not always) I'm get an exception:
如何正确地重用/缓存Client / WebTarget?是否可以使用JAX RS Client API?或者我必须使用一些特定于框架的功能(resteasy / jersey)你能提供一些示例或文档吗?
How can Client/WebTarget be reused/cached correctly? Is it possible with JAX RS Client API? Or I have to use some framework-specific features (resteasy/jersey) Could you provide some example or documentation?
推荐答案
您的实施不是线程安全的。当两个线程同时访问 someMethod
时,他们共享相同的客户端
,并且会尝试发出第二个请求而第一个没有完成。
Your implementation is not thread-safe. When two threads access someMethod
at the same time they are sharing the same Client
and one will try to make a second request while the first one is not finished.
您有两种选择:
- 同步对<$ c的访问权限$ c>客户端和
WebTarget
手动。 - 让容器通过注释封闭类型来管理并发
@ javax.ejb.Singleton
保证线程安全。 (参见)
- Synchronize the access to the
Client
andWebTarget
manually. - Let the container manage concurrency by annotating the enclosing type with
@javax.ejb.Singleton
which guarantees thread safety. (see chapter 4.8.5 of the EJB specification)
如果 someMethod
在容器管理环境中,我会使用第二种方法。
If someMethod
in a container managed environment I would use the second approach.
这篇关于在多线程环境中重用JAX RS Client(具有resteasy)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!