NIO中的事件登记顺序是否重要?

时间:2016-07-15 00:02:23

标签: java selector nio

在java NIO中使用Selector的规范方法是:

  1. 使用ServerSocketChannel事件类型注册SelectionKey.OP_ACCEPT
  2. 在循环方法中调用select方法(阻塞线程)
  3. 然后发生OP_ACCEPT事件,并调用相对AcceptEventHandler接受SocketChannel
  4. 然后使用SocketChannel事件类型注册已接受的SelectionKey.OP_READ
  5. 当读取事件发生时,ReadEventHandler处理输入,然后使用SocketChannel事件类型注册SelectionKey.OP_WRITE
  6. 我的问题是,为什么不在开始时立即注册三种事件类型?顺序是否有意义?

2 个答案:

答案 0 :(得分:1)

  

在java NIO中使用Selector的规范方法是:

不,不是。见下文。

  

为什么不在开始时立即注册三种事件类型?

因为你不能。在您致电accept()之前,您没有接受通道,并且在您注册OP_ACCEPT并将其触发之前您不会这样做,并且您无法注册接受的频道什么,直到你拥有它。

  

序列是否有意义?

else 没有任何意义。

注意,在您遇到短或零长度写入之前,您不会注册OP_WRITE。原因是它几乎总是准备就绪,所以策略只是在你有东西要写的时候写,并且只用OP_WRITE告诉你什么时候可以在短写之后再次写(这意味着套接字发送缓冲区是满)。

答案 1 :(得分:1)

我会尝试在对话中添加内容。

ServerSocketChannel只能accept()个新关联。 OP_READ / OP_WRITE对你没有任何帮助。我非常确定您可以添加它们,但它们只会被忽略,因为ServerSocketChannel's仅对accept()远程SocketChannel负责。

一旦accept()获得新的SocketChannel;你想先听OP_READ。如果您收听OP_WRITE,那么每次拨打OP_WRITE时,您很可能会收到select(),这将消耗大量资源。

当您尝试将一些数据写入OP_WRITE并且并非所有数据都已写入时,您只想听SocketChannel