Jersey2客户端重用不使用AsyncInvoker

时间:2015-03-07 16:25:57

标签: asynchronous client jersey-2.0

我正在尝试重用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对象的建议,也可能是如何解决这个问题。

0 个答案:

没有答案