Java 处理多个客户端的单线程中的SocketChannel.write()

Java 处理多个客户端的单线程中的SocketChannel.write(),java,nio,socketchannel,Java,Nio,Socketchannel,我的应用程序内部有一个队列,队列中有一个“传出网络数据包”(一个POJO,其中有一个ByteBuffer和一个SocketChannel),由一个将数据写入SocketChannel的线程使用 我这样做是为了保证每一个应该接收数据包的客户机都能轮到自己。这意味着SocketChannel.write()将顺序写入多个客户端(=一次1个) 有人能告诉我这样工作会出什么问题吗?socketchannel是从ServerSocketChannel创建的,因此它们处于阻塞状态 我担心write()操作可

我的应用程序内部有一个队列,队列中有一个“传出网络数据包”(一个POJO,其中有一个
ByteBuffer
和一个
SocketChannel
),由一个将数据写入
SocketChannel
的线程使用

我这样做是为了保证每一个应该接收数据包的客户机都能轮到自己。这意味着
SocketChannel.write()
将顺序写入多个客户端(=一次1个)

有人能告诉我这样工作会出什么问题吗?
socketchannel
是从
ServerSocketChannel
创建的,因此它们处于阻塞状态


我担心
write()
操作可能会阻塞一个客户端,使其他客户端等待…

write()操作确实会在阻塞模式下阻塞。如果想要公平性和单线程,则必须使用非阻塞模式。

如果客户端套接字无法在一次写入(非阻塞)中使用所有数据,则可以关闭客户端。这只会在缓冲区填满时发生,因此您可以将套接字的发送缓冲区增加到您可以轻松完成此操作的水平。

您不使用Netty有什么原因吗?如果其他客户端在另一个客户端之前或之后收到了他的数据包,为什么客户端会在意?他怎么会知道呢?他可能关心的是如何快速获取数据包,而多线程可以做到这一点。@JBNizet:我只是认为,当服务器负载为100%时,保证一个客户端不必“永远”等待获取数据包是有意义的,JVM决定忽略该线程。我认为JVM是被允许这样做的。@tolitius:完全没有理由,我只是在试验。如果你能告诉我在哪里查看Netty,我会这么做。如果操作系统确实忽略了线程(调度程序在操作系统中的位置),那么它也可以忽略你的主线程,你的所有客户端都将永远等待。Truts调度程序。它工作得很好。但是如果我想在处理下一个包之前写完整的包,我仍然有问题。或者你有什么建议?我只认为有一个队列和一个消费者线程有利于公平,我并不是说它真的是,我愿意接受建议,这是为了一个我为了好玩而做的测试项目……我认为公平在这里并不重要。假设你去一家超市,有3个客户,每个客户都有不同的出纳。您将到达并在第四个出纳处付款。如果你比其他三位客户先离开超市,他们会在意吗?你要实现公平,就要为所有客户设立一个收银员:超市里会有愤怒的客户。@AndrewBourgeois我不明白你的评论与我的回答有什么关系。(a) 为什么要在处理下一个数据包之前写入完整的数据包?客户端无法判断,并且(b)在为一个客户端提供服务时阻塞整个服务器是不公平的。@EJP:(a)对,我可以将包含剩余数据的缓冲区放在队列的末尾。(b) 所以你同意JB Nizet,我应该放弃这个想法,只在客户端的线程中写入,因为队列的想法更糟糕?