5

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

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

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

所以 - 对我来说,从不同的线程发送超过 64kb 的数据似乎是不安全的,但如果它小于 64kb,它应该是安全的......但我很可能在这里遗漏了一些重要的东西。这里有没有其他人看过这个并得出不同的结论?

4

2 回答 2

5

我认为如此严重地依赖可能超出您控制范围的事物的实现细节是一个非常糟糕的主意。如果你做这样的事情,你将不得不非常小心地控制你使用的所有东西的版本,以确保它是你所期望的,而这很难做到。而且您还必须有一个非常强大的测试套件来验证多线程操作是否正确运行,因为您的解决方案依赖于代码检查和来自 StackOverflow 上随机数的谣言。

为什么不能将 SocketOutputStream 包装到另一个直通 OutputStream 中,然后在该级别添加必要的同步?这样做会更安全,而且您在路上遇到意外问题的可能性要小得多。

于 2012-05-07T23:21:39.760 回答
2

根据此文档http://www.docjar.com/docs/api/java/net/SocketOutputStream.html,该类并未声称是线程安全的,因此假设它不是。它继承自 FileOutputStream,通常文件 I/O 本身并不是线程安全的。

我的建议是,如果该类与硬件或通信有关,则它不是线程安全的或“阻塞”的。原因是线程安全操作消耗更多时间,您可能不喜欢。我的背景不是 Java,但其他库在哲学上是相似的。

我注意到你对这门课进行了广泛的测试,但你可以整天测试它很多天,它可能无法证明什么,我的 2 美分。

祝你好运,玩得开心。

汤米奎

于 2012-05-07T23:42:41.990 回答