basichttpclient execute throws "SingleClientConnManager: соединение все еще выделено" почему? - PullRequest
0 голосов
/ 12 марта 2012

Я знаю, что похожие вопросы задают в других местах, но у меня это другое :)

Я использую BasicHttpClient и HttpPoster для отправки материалов в стороннюю службу. Я использую это в сценарии, где у меня есть слушатели JMS, использующие один компонент для публикации. Я не думал, что это было проблемой, так как BasicHttpclient использует SingleClientConnectionManager, а javadoc говорит

This connection manager maintains only one active connection at a time. Even though this class is thread-safe it ought to be used by one execution thread only.

( Thread-Safe является ключевым здесь) Но, когда у меня есть два одновременных запроса, я получаю классический

java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated.

Почему я это понимаю? Я ничего не убираю, так как базовый клиент делает это в соответствии с документами.

мой боб конструктор:

HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, SMS_SOCKET_TIMEOUT);
params.setParameter(CoreConnectionPNames.SO_TIMEOUT, SMS_SOCKET_TIMEOUT);
params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,
            encoding);
params.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET,
            encoding);
httpclient = new DefaultHttpClient(params);

poster = new HttpPost(mtUrl);
poster.setHeader("Content-type", contentType);

responseHandler = new BasicResponseHandler();

мой код для запуска пост-звонка:

public String[] sendMessage(MtMessage mess) throws MtSendException, MtHandlingException {

    StringEntity input;

    try {
        String postBody = assembleMessagePostBody(mess);
        input = new StringEntity(postBody);
        poster.setEntity(input);
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String response = httpclient.execute(poster, responseHandler);
        return new String[]{extractResponseMessageId(response)};
    } catch(HttpResponseException ee){
        throw new MtSendException(ee.getStatusCode(), ee.getMessage(), false);
    } catch (IOException e) {
        throw new MtSendException(0, e.getMessage(), false);
    } finally{

    }
}

Я подумал, что хотя sendMessage можно вызывать из нескольких потоков JMS-слушателей одновременно, это будет потокобезопасным, поскольку обработчик соединений является потокобезопасным. Думаю, я мог бы просто синхронизировать метод sendMessage ().

Если у кого-то есть вклад, я был бы очень благодарен.

1 Ответ

1 голос
/ 15 марта 2012

SingleClientConnectionManager является полностью поточно-ориентированным в том смысле, что при использовании несколькими потоками выполнения его внутреннее состояние синхронизируется и всегда согласовано. Это не меняет того факта, что он может обойтись только одним соединением. Таким образом, если два потока пытаются арендовать соединение, успешным может быть только один, в то время как другой может получить «java.lang.IllegalStateException: недопустимое использование SingleClientConnManager»

Вы должны использовать диспетчер соединений пула, если ваше приложение должно выполнять запросы одновременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...