用于套接字输入和输出的独立线程

时间:2009-11-17 13:18:01

标签: java multithreading oop sockets legacy-code

我被分配到多线程java服务器的一些性能和随机崩溃问题。尽管线程和线程安全对我来说并不是真正的新主题,但我发现设计一个新的多线程应用程序可能比尝试调整一些遗留代码困难一半。我浏览了一些着名的书籍以寻找答案,但奇怪的是,只要我阅读并分析所提供的例子,一切看起来都很清楚。然而,第二个我看看我应该工作的代码,我不再确定任何事情!必须是太多的理论知识和一些现实世界的经验或其他东西。

无论如何,回到主题,因为我正在进行一些在线研究,我遇到了this piece of code。一直困扰着我的问题是:在没有同步的情况下从两个独立的线程调用套接字上的getInputStream()和getOutputStream()是否真的安全?或者我现在对整个问题有点过于偏执线程安全问题?猜猜这就像连续第5本书中的情况一样,告诉你并发可能出现多少问题。

PS。对不起,如果这个问题有点冗长或者说'noobie',请对我这么容易 - 这是我在这里的第一篇文章。

编辑:为了清楚起见,我知道套接字在全双工模式下工作,并且可以安全地同时使用它们的输入和输出流。当你在主线程中获取这些引用然后使用那些引用初始化线程对象时,我觉得很好,但是获取两个不同线程中的那些流也是安全的吗?

@rsp:

所以我检查了Sun的代码,PlainSocketImpl对这两种方法进行了同步,就像你说的那样。但是,Socket没有。 getInputStream()getOutputStream()几乎只是SocketImpl的包装器,因此可能并发问题不会导致整个服务器爆炸。但是,有点不幸的时间,似乎可能出错(例如当某个其他线程在方法已经检查错误条件时关闭套接字)。

正如您所指出的,从代码结构的角度来看,为每个线程提供流引用而不是整个套接字是个好主意。我可能已经重构了我正在处理的代码,如果不是因为每个线程也使用套接字的close()方法(例如当套接字接收“shutdown”命令时)。据我所知,这些线程的主要目的是将消息排队以便发送或处理,因此可能是单一责任原则违规,并且这些线程不能关闭套接字(与{{3}比较) })?但是如果我长时间分析代码,看起来设计通常是有缺陷的,整个过程需要重写。即使管理层愿意付出代价,认真重构遗留代码,没有任何单元测试以及处理难以调试的并发问题,也可能弊大于利。不是吗?

1 个答案:

答案 0 :(得分:3)

套接字的输入流和输出流表示两个单独的数据流或通道。使用它们之间未同步的线程中的两个流完全保存。套接字流本身将阻止在空缓冲区或完整缓冲区上进行读写。

编辑:来自Sun的套接字实现类会同步getInputStream()getOutputStream()方法,然后从不同的线程调用应该没问题。我同意你的观点,即从代码结构的角度来看,使用它们将流传递给线程可能更有意义(依赖注入有助于测试)。