luk*_*m00 6 java sockets oop multithreading legacy-code
我被分配到多线程java服务器的一些性能和随机崩溃问题.尽管线程和线程安全对我来说并不是真正的新主题,但我发现设计一个新的多线程应用程序可能比尝试调整一些遗留代码困难一半.我浏览了一些着名的书籍以寻找答案,但奇怪的是,只要我阅读并分析所提供的例子,一切看起来都很清楚.然而,第二个我看看我应该工作的代码,我不再确定任何事情!必须是太多的理论知识和一些现实世界的经验或其他东西.
无论如何,回到主题,因为我正在做一些在线研究,我遇到了这段代码.一直困扰着我的问题是:在没有同步的情况下从两个独立的线程调用套接字上的getInputStream()和getOutputStream()是否真的安全?或者我现在对整个线程安全问题有点过于偏执?猜猜这就像连续第5本书中的内容一样,告诉你有多少东西可能出现并发问题.
PS.对不起,如果这个问题有点冗长或者说'noobie',请放轻松 - 这是我在这里的第一篇文章.
编辑:为了清楚起见,我知道套接字在全双工模式下工作,并且可以安全地同时使用它们的输入和输出流.当您在主线程中获取这些引用然后使用这些引用初始化线程对象时,我似乎很好,但是在两个不同的线程中获取这些流也是安全的吗?
@rsp:
所以我检查了Sun的代码,然后PlainSocketImpl就这两种方法进行同步,就像你说的那样.Socket但是,没有.getInputStream()并且getOutputStream()几乎只是包装器SocketImpl,所以可能并发问题不会导致整个服务器爆炸.但是,有一些不幸的时机,似乎事情可能会出错(例如,当方法已经检查错误条件时,某些其他线程关闭套接字).
正如您所指出的,从代码结构的角度来看,为每个线程提供流引用而不是整个套接字是个好主意.我可能已经重构了我正在处理的代码,如果不是因为每个线程也使用套接字的close()方法(例如当套接字接收"shutdown"命令时).据我所知,这些线程的主要目的是将消息排队以便发送或处理,因此可能是单一责任原则违规,并且这些线程不能关闭套接字(与分离的调制解调器接口相比) ?但是如果我长时间分析代码,看起来设计通常是有缺陷的,整个过程需要重写.即使管理层愿意付出代价,认真重构遗留代码,没有任何单元测试以及处理难以调试的并发问题,也可能弊大于利.不是吗?
套接字的输入流和输出流代表两个独立的数据流或通道。在它们之间不同步的线程中使用两个流可以完美保存。套接字流本身将阻止对空或满缓冲区的读取和写入。
编辑:Sun 的套接字实现类会同步getInputStream()和getOutputStream()方法,然后从不同线程调用应该没问题。不过,我同意您的观点,从代码结构的角度来看,将流传递到使用它们的线程可能更有意义(例如,依赖注入有助于测试。)