这可能是一个非常基本的问题,但我很难找到答案。
是否可以让一个线程写入Socket的输出流,而另一个线程正在从Socket的输入流中读取?
编辑:这是与外部服务器通信的客户端应用程序。我并不是想让两个线程相互通信。抱歉模棱两可。
答案 0 :(得分:5)
假设您的意思是线程使用相同的套接字与外部actor进行通信而不是彼此进行通信,这很常见,因为您在等待从套接字读取时通常不希望阻塞。
线程1:
block on read
on recieve message - do something
线程2:
do things
on something happening - write to socket
如果你只是意味着内部有两个线程进行通信,那么你应该研究非套接字的替代方案。
编辑:还要注意潜在的并发问题,因此请检查您使用的流是否是线程安全的。
答案 1 :(得分:2)
人们对你的问题感到困惑,这就是为什么有一半说“是的,但这不是两个线程应该如何相互通信”,而另一个则将你的问题解释为“我希望一个线程始终写入套接字” ,另一个线程总是从套接字读取,所以我的程序可以同时发送和接收。“后面的解释意味着这两个线程不是使用套接字来互相交换信息,而是另一个使这个不那么icky的机器。答案是肯定的。套接字是双向的,因此您可以同时发送和接收数据。这并不意味着你必须使用两个线程才能做到这一点。
现在,这非常不寻常。我一直致力于套接字协议(POP,IMAP,HTTP等),我从来没有遇到过这种情况的情况,或者说另一种方式,我从来没有见过要求这种情况发生的协议。在某些时候,协议是同步的,其中一个端点必须等待它发送更多信息或读取更多信息。我能想到的唯一情况是RTMP,音频或视频流。但是,我认为大多数都使用某种形式的非阻塞IO,因此模拟了同步通信。
这是您可能想要考虑的下一件事。当您处理来自套接字的消息时,您可能会在阻塞之前检查套接字是否有数据。如果它在那里读取,如果你有数据要写检查,看看你是否可以不阻塞地写,然后写它。或使用非阻塞IO套接字。这样你只有一个线程读/写一个套接字和读/写之间的同步是没有脑子的。使用线程,您将不得不使用锁定或信号量或其他东西在它们之间进行协调,这可能导致死锁。
答案 2 :(得分:1)
只要您有充分的理由以这种方式进行沟通而不是通过其他线程通信技术,那么执行该操作没有任何问题。
与考虑两个完全不同的应用程序监听/写入同一套接字的概念没有任何不同。
答案 3 :(得分:1)
换句话说,您想使用套接字将信息从一个线程发送到另一个线程?是的,这是可能的。我会强烈考虑一个不同的路线(他们可以互相传递一个参考,所以我认为会更好),但它应该有效。
在了解套接字如何工作以及所涉及的麻烦时,将它们保存在同一个应用程序中通常会大大简化事情,这是我强烈鼓励的。
但对于生产代码,我建议使用引用或线程安全队列或类似的东西。
编辑:回复您的评论和修改:
有两种方法可以做到这一点:相同的线程,您可以获得输入,然后对其做出反应,或使用单独的线程,这样您就可以发送信息而无需接收它们。对于简单的程序,建议使用第一个,因为它是最简单的。但是对于任何超出最简单协议的东西,你都希望第二个线程使输入和输出失去同步。
答案 4 :(得分:1)
你可以有一个线程正在阅读而另一个正在写。 AFAIK这可能是阻塞套接字的最常见用例。
可以让多个线程同时执行这两个操作,但这并不简单,您很少需要多个线程。
您可以在同一进程中进行两个线程通信。这是我在单元测试中经常使用的,我在同一个进程中有客户端和服务器组件。
您甚至可以使用一个线程从两端读取写入。 http://vanillajava.blogspot.com/2011/11/java-puzzle-single-threaded-client.html
备选方案可能是使用稍快一些的Piped Stream,或者使用ByteBuffers或一堆或其他选项的BlockingQueue或Exchange。 ;)
答案 5 :(得分:0)
是的,但您想用什么流来创建“缓冲区”?它必须像BlockingQueue
答案 6 :(得分:0)
是的,你可以,套接字是双向的。 实施协议时要小心。确保同步读写调用,并构建消息框