关于java:BasicClientConnManager的无效使用:连接仍被分配

Invalid use of BasicClientConnManager: connection still allocated

我正在打电话给REST URL,并试图衡量恢复响应所花费的时间。

我正在使用DefaultHttpClient来从REST URL取回响应。

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

在我的以下代码中,

SO第一次正常运行。但是这是第二次,它在该行httpclient.execute上第二次引发异常,原因是-

1
2
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.

我在这里做错什么吗?-

下面是我的代码-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
        }
    }
}

更新的代码:-

如果我正在做这样的事情-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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);
        }
    }
}

那还好吗?


Is there anything wrong I am doing here?

是的。如文档所述:

BasicClientConnectionManager is a simple connection manager that
maintains only one connection at a time. Even though this class is
thread-safe it ought to be used by one execution thread only.
BasicClientConnectionManager will make an effort to reuse the
connection for subsequent requests with the same route. It will,
however, close the existing connection and re-open it for the given
route, if the route of the persistent connection does not match that
of the connection request. If the connection has been already been
allocated, then java.lang.IllegalStateException is thrown.

BasicClientConnectionManager is used by HttpClient per default.

有关如何使用可处理多个线程中的请求的池连接管理器,请参见"多线程请求执行"。


假设您使用的是香草DefaultHttpClient(内部使用BasicClientConnectionManager),则首先需要消耗未完成/最后的响应。

EntityUtils.consumeQuietly(httpResponse.getEntity());

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

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


这是我使用池连接管理器为RestTemplate进行的配置。它在另外5个并发线程中工作得很好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- RestTemplate -->
<beans:bean id="restTemplateYT" class="org.springframework.web.client.RestTemplate">
    <beans:constructor-arg ref="httpRequestFactoryYT" />
</beans:bean>

<beans:bean id="httpRequestFactoryYT" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
    <beans:constructor-arg>
        <beans:bean class="org.apache.http.impl.client.DefaultHttpClient">
            <beans:constructor-arg>
                <beans:bean class="org.apache.http.impl.conn.PoolingClientConnectionManager"/>
            </beans:constructor-arg>
        </beans:bean>
    </beans:constructor-arg>
    <beans:property name="connectTimeout" value="5000" />
</beans:bean>

Spring版本:3.1.0