2010-07-17 4 views
4

Является ли HttpUrlConnection потоком безопасным? То есть если у меня есть экземпляр HttpConnection, подключенный к серверу, и этот экземпляр используется разными потоками (например, для отправки POST одновременно), как эта ситуация будет обрабатываться HttpUrlConnection? а) Будут ли они отправлять POST последовательно, или б) первый поток отправляет POST, получает ответ, а затем второй поток отправляет POST? Если они посылают POST последовательно, это означает, что несколько активных POST для одного и того же соединения tcp. Это разрешено? Может ли это быть обработано сервером?httpurlconnection thread safety

Thanks

+1

Я сомневаюсь, что базовый сокет не может быть потокобезопасным, по крайней мере, вы получите повреждение сообщения. –

+0

Что вы подразумеваете, говоря, что базовый сокет не может быть потокобезопасным? Он не реализован как синхронизированный? – Cratylus

ответ

4

Он не говорит, что это или нет в документах. Посмотрев код (http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/net/sun/net/www/protocol/http/HttpURLConnection.java.htm), похоже, что getInputStream и getOutputStream синхронизированы. У меня есть проблема в том, что если у вас есть поток, который получает входной поток, и в то же время у вас есть другой поток, который получает выходной поток, вы можете получить свои сигналы. inputStream и outputStream - это переменные экземпляра, которые, вероятно, не должны использоваться совместно нитями.

Если бы я был вами, я бы выполнил очередь, которая позволит вам отправлять сообщения в очередь и затем отправлять их на сервер по одному. Когда запрос возвращается, вы просто вызываете обратный вызов. Это гарантирует, что запрос не был отправлен до того, как ответ вернется.

+0

То, что вы говорите, имеет большой смысл. Мне было интересно, хотя, если вместо худшего случая с пересечением сигналов у нас было следующее: thread1 и thread2 делиться httpurlconnection. Оба потока пытаются выполнить POST. Thread2 будет блокироваться с момента синхронизации getOutputStream. Thread1 завершает запись запроса и блокирует входной поток для результата. Thread2 получает выходной поток и записывает POST. Затем thread2 блокирует входной поток. На данный момент в одном подключении tcp есть 2 активных POST. Есть ли вероятность, что сервер сможет справиться с этим? Чтобы ответы пришли в правильном порядке? – Cratylus

+0

@ user384706 В документации не сказано, что это безопасный поток, в коде говорится, что только определенные части синхронизированы и что вам нужно будет добавить слой сверху, чтобы сделать его потокобезопасным. Выполняя это самостоятельно, вы подвергаетесь серьезному риску, если это не удастся, вам будет сложно определить проблемы. Если бы я был вами, я бы посмотрел на реализацию, которая задокументирована как Thread Safe, например http://hc.apache.org/httpclient-3.x/threading.html, и не стоит беспокоиться об этом. –

+0

@Romain Hippeau Что делать, если мы создадим новый экземпляр HttpUrlConnection, который имеет одинаковый URL для каждого потока? будет ли какой-нибудь недостаток? – dpanshu

13

это не безопасный поток.

вы не должны кэшировать/совместно использовать соединение. просто создайте новое соединение для каждого запроса. в создании новых подключений, конечно, немного накладных расходов, но он очень мал, вы не должны беспокоиться об этом.

спирт HTTP на самом деле не подключен. нет, семантически, связи между клиентом и сервером. клиент отправляет запрос, сервер отправляет ответ, то есть все.

Хотя сегодня HTTP действительно определен поверх TCP, который является протоколом с подключением, а HTTP может использовать долгое TCP-соединение для нескольких запросов/ответов, это не характер HTTP.

поскольку обмен запрошенным ответом может быть реализован поверх большинства сетевых протоколов, изначально HTTP разрешил возможность указания базовых протоколов. Мы можем представить http-запрос/ответный обмен по электронной почте - http:/smtp/www.example.com; возможно, RMI - http:/rmi/www.example.com; по умолчанию используется TCP, поэтому http:// действительно означает http:/tcp/

Сегодня используется только TCP, и мы остаемся с этим любопытным разделителем двойной косой черты. но это напоминание о том, что зависимость HTTP от TCP довольно случайна.

+0

Я понимаю, что вы говорите. Но разве вы не советуете создавать новое соединение для запроса с использованием подхода HTTP1.0? Также, говоря, что я не должен кэшировать соединение, вы фактически имеете в виду избежать схем объединения пулов? Мое намерение состояло в том, чтобы повторно использовать установленное соединение с помощью нескольких запросов, чтобы избежать накладных расходов на 3-х стороннее рукопожатие. Кроме того, мне было интересно, могу ли я «нажимать» несколько запросов POST на одно и то же соединение tcp. Неужели я полностью вне игры? – Cratylus

+0

, если вы действительно заботитесь о производительности, откройте сырое TCP-соединение и напишите ему ваши запросы. Попробуйте, это удивительно просто, поскольку HTTP - это простой дизайн. У вас может быть несколько потоков, связанных с одним и тем же TCP-соединением, но тогда вам нужно синхронизировать, чтобы только один поток выполнял это за раз. Вам лучше с одним подключением на поток.Если у вас открыто несколько подключений к серверу, ваша пропускная способность, скорее всего, будет улучшена. – irreputable

+0

Когда вы говорите «несколько потоков, записывающих одно и то же TCP-соединение», однако тогда вам нужно синхронизировать, чтобы только один поток выполнял это за один раз », вы имеете в виду, что каждый поток отправляет POST и получает ответ, а затем следующий поток принимает TCP связь? Извините, но мне непонятно, как использование необработанного tcp-соединения - это улучшение по сравнению с использованием httpurlconnection? Почему бы просто не синхронизировать доступ httpurlconnection? Не могли бы вы объяснить это больше? – Cratylus