BasicClientConnManager的使用无效:仍然分配了连接

AKI*_*WEB 40 java rest apache-httpclient-4.x

我正在调用REST URL并尝试测量恢复响应所花费的时间.

我正在用DefaultHttpClient它来获得回复REST URL.

在我的下面的程序中,每个线程将在特定范围内工作.像每个线程将工作之间1 - 100和第二个线程将工作之间101 - 200等.

在我的下面的代码中,它第一次正常工作.但这是第二次,它在这条线上httpclient.execute第二次抛出异常-

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
Run Code Online (Sandbox Code Playgroud)

我在这里做错了吗? -

以下是我的代码 -

class Task implements Runnable {

    private DefaultHttpClient httpclient = new DefaultHttpClient();
    private HttpGet httpGet;
    private HttpResponse response;

    @Override
    public void run() {

        try {

            httpGet = new HttpGet(
                    "http://localhost:8080/service/BEService/v1/get/USERID=10000/profile.ACCOUNT.SERVICE
            httpGet.getRequestLine();

            for (int userId = id; userId < id + noOfTasks; userId++) {

                    long start = System.nanoTime();

                    response = httpclient.execute(httpGet);

                    long end = System.nanoTime() - start;
                }
        } catch (Exception e) {
            LOG.error("Threw a Exception in " + getClass().getSimpleName(), e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新的代码: -

如果我这样做的话 -

class Task implements Runnable {

    private DefaultHttpClient httpclient = new DefaultHttpClient();
    private HttpGet httpGet;
    private HttpResponse response;

    @Override
    public void run() {

        try {

            for (int userId = id; userId < id + noOfTasks; userId++) {

                httpGet = new HttpGet("http://localhost:8080/service/BEService/v1/get/USERID=10000/profile.ACCOUNT.SERVICE");
                httpGet.getRequestLine();

                long start = System.nanoTime();

                response = httpclient.execute(httpGet);

                long end = System.nanoTime() - start;

                HttpEntity entity = response.getEntity();
                EntityUtils.consume(entity);
                }
        } catch (Exception e) {
            LOG.error("Threw a Exception in " + getClass().getSimpleName(), e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么它还好吗?

Rya*_*art 44

我在这里做错了吗?

是.如文档所述:

BasicClientConnectionManager是一个简单的连接管理器,一次只能维护一个连接.即使这个类是线程安全的,它也应该只由一个执行线程使用.BasicClientConnectionManager将努力为具有相同路由的后续请求重用连接.它将,但是,关闭现有的连接并重新打开它对于给定的路线,如果持续连接的路由不匹配的连接请求.如果已经分配了连接,则抛出java.lang.IllegalStateException.

默认情况下,HttpClient使用BasicClientConnectionManager.

有关如何使用可以跨多个线程处理请求的池连接管理器,请参阅"多线程请求执行".


kev*_*rpe 41

假设您正在使用vanilla DefaultHttpClient(在BasicClientConnectionManager内部使用),您首先需要使用未完成/最后一个响应.

EntityUtils.consumeQuietly(httpResponse.getEntity());

否则,您可以DefaultHttpClient每次重新分配.

来源:解决方法是每次使用后不关闭DefaultHttpClient()