如何在一个线程中读取SocketChannel,并从n个线程写入?

时间:2017-10-22 13:08:11

标签: java multithreading sockets nio

我有一个socketChannel(java.nio.channels.SocketChannel)监听读取请求(来自多个客户端)。它将每个请求存储在请求队列中。

另外socketChannel.configureBlocking(false)

然后我希望多个线程一次从R equest Queue 获取一个请求并写入socketChannel

我从文档中读到了以下内容。

  

多个并发线程可以安全地使用套接字通道。他们   支持并发读写,但最多只有一个线程可以   阅读,最多一个帖子可能在任何给定时间写作。

由于只能写入1个线程,在多次写入的情况下我该怎么办?

2 个答案:

答案 0 :(得分:2)

您可以使用自己的锁synchronizedReentrantLock,或者对消息进行排队,让一个线程执行实际的写操作。

写入的问题是你一次只能原子地写一个字节,如果你写了多个字节,你可能会发送一些但不是所有的数据,在这种情况下,另一个线程可以尝试写它#39 ; s消息,你得到一个损坏的消息。

答案 1 :(得分:1)

  

我有java.nio.channels.SocketChannel监听读取请求(来自多个客户端)。

不,不。对于来自多个客户端的 connections ,您可能有<{1>} 侦听,但是一旦您拥有了已接受的ServerSocketChannel,它就只连接到一个客户端。您可以从中获得所有来自该客户端的顺序请求。

  

它将每个请求存储在请求队列中。

我认为没有必要。

  

另外SocketChannel

     

然后我希望多个线程一次从请求队列中获取一个请求并写入socketChannel.configureBlocking(false)

为什么不在阅读后立即计算回复并直接写回来?

  

我从文档中读到了以下内容。

     
    

多个并发线程可以安全地使用套接字通道。它们支持并发读写,但最多只有一个线程可能正在读取,并且最多一个线程可能在任何给定时间写入。

  
     

由于只能写入1个线程,在多次写入的情况下我该怎么办?

多次写入?每个频道只有一个客户端请求。您只需要为每个请求写一个响应。在您编写先前的回复之前,您不应该阅读,更不用说处理新请求了。