java - 套接字输入和输出的独立线程

标签 java multithreading oop sockets legacy-code

我被指派处理多线程 Java 服务器的一些性能和随机崩溃问题。尽管线程和线程安全对我来说并不是真正的新主题,但我发现设计一个新的多线程应用程序的难度可能只有尝试调整一些遗留代码的一半。我浏览了一些知名书籍以寻找答案,但奇怪的是,只要我阅读它并分析提供的示例,一切似乎都很清楚。然而,当我看到我应该处理的代码时,我对任何事情都不确定了!一定是理论知识太多,实际经验太少之类的。

无论如何,回到主题,当我在做一些在线研究时,我遇到了 this piece of code .一直困扰我的问题是:在没有同步的情况下从两个单独的线程调用套接字上的 getInputStream() 和 getOutputStream() 真的安全吗?或者我现在对整个过程有点过于偏执了线程安全问题?猜猜这就是连续第 5 本书告诉您并发可能出错的情况。

附言。抱歉,如果问题有点冗长或者太“菜鸟”,请放轻松 - 这是我在这里的第一篇文章。

编辑: 澄清一下,我知道套接字在全双工模式下工作,同时使用它们的输入和输出流是安全的。当您在主线程中获取这些引用然后用它们初始化线程对象时,我觉得这很好,但是在两个不同的线程中获取这些流是否也安全?

@rsp:

所以我检查了 Sun 的代码,PlainSocketImpl 确实在这两个方法上同步,正如您所说。但是,Socket 没有。 getInputStream()getOutputStream() 几乎只是 SocketImpl 的包装器,所以可能并发问题不会导致整个服务器爆炸。尽管如此,由于时机不巧,事情似乎可能出错(例如,当该方法已经检查了错误条件时,其他线程关闭了套接字)。

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

最佳答案

套接字的输入流和输出流代表两个独立的数据流或 channel 。在它们之间不同步的线程中使用两个流是完美的保存。套接字流本身将阻止读取和写入空缓冲区或满缓冲区。

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

关于java - 套接字输入和输出的独立线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1748808/

相关文章:

java - 膨胀布局的 child 不显示

java - 如何解决这个问题 "mail body is not getting displayed in outlook using java"?

c# - 单声道多处理性能问题

c++ - 即使使用 strand,async_writes 的顺序也不正确

java - 更新语句占位符的 JDBC 限制失败的解决方法

java - Android 房间库错误 : Cannot find getter for field

java - 当我将 IntentService 与 ResultReceiver 一起使用时,当我的 Activity 被销毁时会发生什么

python - Python 解释器是否将实例绑定(bind)到方法或 self 参数?

php - 对象方法创建其类的实例

java - 为什么代码会产生以下结果?