我被分配处理多线程 Java 服务器的一些性能和随机崩溃问题。尽管线程和线程安全对我来说并不是真正的新话题,但我发现设计一个新的多线程应用程序可能比尝试调整一些遗留代码困难一半。我浏览了一些知名书籍以寻找答案,但奇怪的是,只要我阅读并分析提供的示例,一切似乎都很清楚。然而,当我看到我应该处理的代码时,我什么都不确定了!一定是理论知识太多,现实经验少之类的。
无论如何,回到主题,当我在做一些在线研究时,我遇到了这段代码。一直困扰我的问题是:在没有同步的情况下从两个单独的线程调用套接字上的 getInputStream() 和 getOutputStream() 真的安全吗?还是我现在对整个线程安全问题有点过于偏执了?猜猜这就是当连续第五本书告诉你并发有多少事情可能出错时发生的事情。
PS。抱歉,如果这个问题有点冗长或者太“noobie”,请对我放轻松——这是我在这里的第一篇文章。
编辑:为了清楚起见,我知道套接字在全双工模式下工作,同时使用它们的输入和输出流是安全的。当您在主线程中获取这些引用然后用它们初始化线程对象时,对我来说似乎很好,但是在两个不同的线程中获取这些流也安全吗?
@rsp:
PlainSocketImpl
因此,正如您所说,我检查了 Sun 的代码并在这两种方法上进行了同步。Socket
,然而,没有。getInputStream()
并且getOutputStream()
几乎只是 的包装器SocketImpl
,因此并发问题可能不会导致整个服务器爆炸。尽管如此,在一些不幸的时机下,似乎事情可能会出错(例如,当方法已经检查错误条件时,当某个其他线程关闭套接字时)。
正如您所指出的,从代码结构的角度来看,为每个线程提供流引用而不是整个套接字是一个好主意。close()
如果不是因为每个线程也使用套接字的方法(例如,当套接字接收“关闭”命令时),我可能已经重组了我正在处理的代码。据我所知,这些线程的主要目的是将消息排队以进行发送或处理,因此可能违反了单一职责原则,并且这些线程不应该能够关闭套接字(与分离调制解调器接口相比))? 但是如果我继续分析代码太久,看起来设计通常是有缺陷的,整个事情都需要重写。即使管理层愿意付出代价,认真重构遗留代码、没有单元测试以及处理难以调试的并发问题,也可能弊大于利。不会吗?