Java nio操作单元读操作和操作单元写操作之间的通信

Java nio操作单元读操作和操作单元写操作之间的通信,java,nio,Java,Nio,为了好玩,我尝试实现基于java.nio选择器的http服务器。在key.isReadable上,我读取的数据如下: ByteBuffer buf = ByteBuffer.allocate(4096); SocketChannel client = (SocketChannel) key.channel(); //Gathering whole client request ((ByteBufferQueue) key.attachment()).enqueue(buf); key.inter

为了好玩,我尝试实现基于java.nio选择器的http服务器。在key.isReadable上,我读取的数据如下:

ByteBuffer buf = ByteBuffer.allocate(4096);
SocketChannel client = (SocketChannel) key.channel();
//Gathering whole client request
((ByteBufferQueue) key.attachment()).enqueue(buf);
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);

请查看收集客户的请求。在OP_读取操作期间,在某种队列中收集ByteBuffers是否是一种常见做法?在操作单元读操作和操作单元写操作之间是否还有其他更好的通信方式?

为每个接受的通道分配一个ByteBuffer,并将其保存为密钥附件,或保存在用作密钥附件的会话对象中,其中可能还包含其他内容

当OP_READ发生火灾时,您应该阅读。不要在排队的时候胡闹


NB OP_WRITE几乎总是准备就绪,除非套接字发送缓冲区已满。因此,将其注册为InterestTop是不正确的,除非套接字缓冲区已满,您可以通过写入返回零来检测。在其他任何时候,当你有东西要写的时候,你应该写。如果write返回零,则注册OP_write而不是OP_READ,当获得它时,重试写入:如果写入完成,则取消注册OP_write并注册OP_READ。如果您一直注册OP_WRITE,选择器将不会等待,它只会旋转。

为每个接受的通道分配一个ByteBuffer,并将其保存为密钥附件,或保存在用作密钥附件的会话对象中,该对象可能还包含其他内容

当OP_READ发生火灾时,您应该阅读。不要在排队的时候胡闹


NB OP_WRITE几乎总是准备就绪,除非套接字发送缓冲区已满。因此,将其注册为InterestTop是不正确的,除非套接字缓冲区已满,您可以通过写入返回零来检测。在其他任何时候,当你有东西要写的时候,你应该写。如果write返回零,则注册OP_write而不是OP_READ,当获得它时,重试写入:如果写入完成,则取消注册OP_write并注册OP_READ。如果您一直注册OP_WRITE,选择器将不会等待,它只会旋转。

对不起,我可以劫持您的答案来询问更多细节吗?现在我需要在OP_READ和一些工作线程之间传递数据。我再一次通过一些附加到客户机密钥的作业对象和ConcurrentLinkedQueues,通过缓存请求和响应。当responseQueue不为空时,我不会写。这都是个好主意吗?在编写代码时,它看起来不错,但性能会很好吗?不,您应该按照我描述的方式使用Op_WRTIE。但是生成回复的工作线程在单独的线程中运行。我不能只是给它缓冲。我需要以某种方式同步工作人员。传递缓冲区副本而不是队列?@Oroboros您可以直接从工作线程写入通道。工作线程确实需要知道将响应放在何处,这意味着他需要通道和写入缓冲区或会话对象,无论您使用哪个对象。对不起,我可以劫持您的答案来询问更多细节吗?现在我需要在OP_READ和一些工作线程之间传递数据。我再一次通过一些附加到客户机密钥的作业对象和ConcurrentLinkedQueues,通过缓存请求和响应。当responseQueue不为空时,我不会写。这都是个好主意吗?在编写代码时,它看起来不错,但性能会很好吗?不,您应该按照我描述的方式使用Op_WRTIE。但是生成回复的工作线程在单独的线程中运行。我不能只是给它缓冲。我需要以某种方式同步工作人员。传递缓冲区副本而不是队列?@Oroboros您可以直接从工作线程写入通道。工作线程确实需要知道将响应放在何处,这意味着他需要通道和写入缓冲区或会话对象,无论您使用哪个对象。