有没有办法取消一个密钥,以便我以后仍然可以用java nio读取它

时间:2012-12-11 02:46:40

标签: java netty nio mina

我们希望将tcp流控制作为新java nio库的主要组件。它会像这样工作......

  1. 库将数据激发到Listener.incomingData(DataChunk dataChunk);
  2. 库不会再触发任何数据,如果有任何数据,则直到调用dataChunk.processed()。
  3. 通常,您可以在前几个dataChunks上调用processed()方法,但是在某个消息的最后一个上,您可以写入某个远程套接字并为其提供一个回调处理程序。
  4. 一旦调用了write回调,就会调用最后一个dataChunk.processed()来再次释放tcp流量控制
  5. 大注:第2步是如果你没有从nic缓冲区读取,tcp流控制会自动启动。这都是自动的(我们用java nio测试它)。但问题是我们如何将密钥置于轮询器STOPS释放的状态,并等待除此之外的所有OTHER套接字上的数据。我不介意它是否在它有新数据时发布,因为我们会看到最后一个dataChunk尚未处理并忽略它,但我们不希望轮询器线程循环100%cpu。有没有办法实现这一点,所以我们可以使用这个潜在的开源nio框架为任何服务器实现自动限制。

2 个答案:

答案 0 :(得分:1)

不,选择器会查看其内部状态而不是来自系统的事件,因此关键时刻 设置为检测可读数据,当数据在缓冲区中等待时,它将始终返回 请阅读。

您有三种选择

从缓冲区读取数据并在从上一个块等待的同时在本地存储 过程

从选择器中取消注册密钥,并在处理完块时重新注册。

将密钥设置为在处理块时不感知可读和重置。

我认为这就是你想要的,切换阅读兴趣

selectionKey.interestOps(selectionKey.interestOps() ^ SelectionKey.OP_READ);

答案 1 :(得分:1)

只需取消它并稍后重新注册该频道,或者只需更改其OP_READ,即可取消注册interestOps(),并在您准备再次阅读时将其更改回来。< / p>