SocketOutputStream的线程安全性 [英] Thread safety of SocketOutputStream

查看:154
本文介绍了SocketOutputStream的线程安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道Java套接字的线程安全性已经在stackoverflow上的几个线程中讨论过,但是我还没有找到这个问题的明确答案 - 在实践中,是否可以安全地让多个线程同时写入对于相同的SocketOutputStream,还是存在从一个线程发送的数据与来自另一个线程的数据混淆的风险? (例如,另一端的接收器首先接收一个线程消息的前半部分,然后接收另一个线程消息的一些数据,然后接收第一个线程消息的其余部分)



我之所以说实践中的原因是我知道Socket类没有记录为线程安全的,但如果它在当前的实现中实际上是安全的,那么这对我来说已经足够了。我最感兴趣的具体实现是在Linux上运行的Hotspot。



在查看热点实现的Java层时,更具体地说是SocketOutputStream中socketWrite()的实现,看起来它应该是线程安全的,只要本机实现socketWrite0()的安全性。但是,在查看该方法的实现时(j2se / src / solaris / native / java / net / SocketOutputStream.c),它似乎将要发送的数据拆分为64或128kb的块(取决于它是否为64位) JVM)然后以单独写入的方式发送块。



所以 - 对我来说,看起来从不同的线程发送超过64kb是不安全的,但如果它低于64kb它应该是安全的...但我可以很遗憾,这里缺少一些重要的东西。这里有没有人看过这个并得出不同的结论?

解决方案

我认为这是真的糟糕的想法如此严重依赖于某些可能会发生变化的实施细节。如果你做这样的事情,你将必须非常小心地控制你使用的所有的版本,以确保它符合你的期望,这是非常困难的。此外,您还必须拥有一个非常强大的测试套件,以验证多线程操作是否正常运行,因为您依赖于代码检查以及StackOverflow上用于解决方案的传言。



<为什么不能将SocketOutputStream包装到另一个直通OutputStream中,然后在该级别添加必要的同步?以这种方式做得更安全,你在未来遇到意外问题的可能性要小得多。


I know that thread safety of java sockets has been discussed in several threads here on stackoverflow, but I haven't been able to find a clear answer to this question - Is it, in practice, safe to have multiple threads concurrently write to the same SocketOutputStream, or is there a risk that the data sent from one thread gets mixed up with the data from another tread? (For example the receiver on the other end first receives the first half of one thread's message and then some data from another thread's message and then the rest of the first thread's message)

The reason I said "in practice" is that I know the Socket class isn't documented as thread-safe, but if it actually is safe in current implementations, then that's good enough for me. The specific implementation I'm most curious about is Hotspot running on Linux.

When looking at the Java layer of hotspot's implementation, more specifically the implementation of socketWrite() in SocketOutputStream, it looks like it should be thread safe as long as the native implementation of socketWrite0() is safe. However, when looking at the implemention of that method (j2se/src/solaris/native/java/net/SocketOutputStream.c), it seems to split the data to be sent into chunks of 64 or 128kb (depending on whether it's a 64bit JVM) and then sends the chunks in seperate writes.

So - to me, it looks like sending more than 64kb from different threads is not safe, but if it's less than 64kb it should be safe... but I could very well be missing something important here. Has anyone else here looked at this and come to a different conclusion?

解决方案

I think it's a really bad idea to so heavily depend on the implementation details of something that can change beyond your control. If you do something like this you will have to very carefully control the versions of everything you use to make sure it's what you expect, and that's very difficult to do. And you will also have to have a very robust test suite to verify that the multithreaded operatio functions correctly since you are depending on code inspection and rumors from randoms on StackOverflow for your solution.

Why can't you just wrap the SocketOutputStream into another passthrough OutputStream and then add the necessary synchronization at that level? It's much safer to do it that way and you are far less likely to have unexpected problems down the road.

这篇关于SocketOutputStream的线程安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆