2010-07-17 146 views
4

HttpUrlConnection线程安全吗?即如果我有一个HttpConnection实例连接到服务器,并且此实例由不同线程使用(例如,如果同时发送POST),那么HttpUrlConnection将如何处理这种情况? a)他们是否会连续发送POST,或者b)第一个线程发送POST,获取响应,然后第二个线程发送POST?如果他们串行发送POST,这意味着多个活动的POST到相同的TCP连接。这是否允许?它可以由服务器处理吗?httpurlconnection线程安全

谢谢

+1

我怀疑它底层套接字不能线程安全,至少你会得到消息腐败。 – 2010-07-17 18:22:55

+0

你说什么底层套接字不能线程安全?它没有实现为同步? – Cratylus 2010-07-17 18:36:07

回答

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。由于getOutputStream已同步,所以Thread2会阻塞。线程1完成写入请求并锁定结果的输入流。 Thread2获取输出流并写入POST。然后在输入流中的thread2块。此时,在同一个tcp连接中有两个活动的POST。服务器可以处理这个问题吗?所以答复按正确的顺序? – Cratylus 2010-07-18 11:11:48

+0

@ user384706文档没有说它是线程安全的,代码表示只有某些部分是同步的,并且您需要在顶部添加一个图层以使线程安全。通过自己这样做,你会面临很大的风险,如果失败了,你将很难找出问题。如果我是你,我会看看被记录为线程安全的实现,例如http://hc.apache.org/httpclient-3.x/threading.html,而不必担心它。 – 2010-07-18 15:37:29

+0

@Romain Hippeau如果我们为每个线程创建一个具有相同URL的HttpUrlConnection的新实例,该怎么办?会有什么缺点吗? – dpanshu 2015-08-06 08:48:11

13

它不是线程安全的。

你不应该缓存/共享连接。只需为每个请求创建一个新的连接。在创建新连接时肯定会有一些额外的开销,但它非常小,您不应该担心。

精神 HTTP实际上是无连接的。从语义上讲,客户端和服务器之间没有连接。客户端发送请求,服务器发回回应,即全部。尽管现在HTTP确实是在TCP之上定义的,而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次握手开销。此外,我想知道是否可以通过同一个tcp连接“推送”多个POST请求。我完全偏离轨道吗? – Cratylus 2010-07-17 20:49:04

+0

如果你真的关心性能,打开一个原始的TCP连接,并写你的请求。尝试一下,它非常简单,因为HTTP是一个简单的设计。您可能有多个线程写入同一个TCP连接,但是,您需要同步,以便一次只有一个线程执行同步。每个线程使用一个连接最好。如果您有多个连接对服务器开放,则吞吐量可能会提高。 – irreputable 2010-07-17 23:34:43

+0

当你说“多个线程写入相同的TCP连接,但是你需要同步,以便一次只有一个线程执行它”,你的意思是每个线程发送POST并获得响应,然后下一个线程将TCP连接?我很抱歉,但我不清楚如何使用原始TCP连接是使用httpurlconnection的改进?为什么不只是同步httpurlconnection访问?你会善意解释这一点吗? – Cratylus 2010-07-18 08:54:54