我正在尝试重用Jersey2(Jersey 2.16)客户端进行异步调用。但是在2次请求之后,我看到线程进入等待状态,等待锁定。由于客户端创建是一项昂贵的操作,我试图在异步调用中重用客户端。仅在ApacheConnectorProvider
作为连接器类时才会出现此问题。我想使用ApacheConnectorProvider
,因为我需要使用代理并设置SSL属性,我想使用PoolingHttpClientConnectionManager
。
示例代码如下:
public class Example {
Integer eventId = 0;
private ClientConfig getClientConfig()
{
ClientConfig clientConfig = new ClientConfig();
ApacheConnectorProvider provider = new ApacheConnectorProvider();
clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING,RequestEntityProcessing.BUFFERED);
clientConfig.connectorProvider(provider);
return clientConfig;
}
private Client createClient()
{
Client client = ClientBuilder.newClient(getClientConfig());
return client;
}
public void testAsyncCall()
{
Client client = createClient();
System.out.println("Testing a new Async call on thread " + Thread.currentThread().getId());
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", eventId++);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
client.close();
}
private void invoker(Client client, String URI, JSONObject jsonObject)
{
final Future<Response> responseFuture = client.target(URI)
.request()
.async()
.post(Entity.entity(jsonObject.toJSONString(), MediaType.TEXT_PLAIN));
try {
Response r = responseFuture.get();
System.out.println("Response is on URI " + URI + " : " + r.getStatus());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[])
{
Example client1 = new Example();
client1.testAsyncCall();
return;
}
}
我看到的回应是:
在线程1上测试新的Async调用 响应在URI http://requestb.in/nn0sffnn上:200
响应在URI http://requestb.in/nn0sffnn上:200
在查看线程堆栈时,我看到以下跟踪:
&#34; Jersey的客户端 - 异步执行人-0&#34; prio = 6 tid = 0x043a4c00 nid = 0x56f0等待条件[0x03e5f000] java.lang.Thread.State:WAITING(停车) 在sun.misc.Unsafe.park(原生方法) - 停车等待&lt; 0x238ee148&gt; (java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject) 在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject.await(AbstractQueuedSynchronizer.java:2043) 在org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:133) at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:282) 在org.apache.http.pool.AbstractConnPool.access $ 000(AbstractConnPool.java:64) 在org.apache.http.pool.AbstractConnPool $ 2.getPoolEntry(AbstractConnPool.java:177) 在org.apache.http.pool.AbstractConnPool $ 2.getPoolEntry(AbstractConnPool.java:170)
有人可以给我一个关于如何为异步请求重用Client对象的建议,也可能是如何解决这个问题。