【问题标题】:concurrent connection using Java NIO使用 Java NIO 的并发连接
【发布时间】:2016-11-10 22:14:24
【问题描述】:

问题的大致轮廓是多线程的 ClientSocketChannel 使用 CPU 超出预期。 一般的东西是具有多线程的ClientSocketChannel。 好的,我应该说我要问的问题之前问过 this question.

还有其他相同答案的帖子。我再次提到它的原因是我真的无法理解答案,因为它并不明显,并且我无法采用我的代码。我试着简单解释一下需求,看看有没有可以涵盖全部需求的答案。

  1. 写入过程应触发填充另一个线程的字节缓冲区
  2. 系统必须意识到写入或读取操作,因为它们中的任何一个都可能首先发生。
  3. 一种防止无用 cpu 运行的方法,似乎 OP_write 在不需要时使其忙碌。

回答:

OP_WRITE的正确使用方法如下:

只为 OP_READ 注册一个新接受的频道

那么我们是只需要一个带有 OP_READ 操作数的通道还是两者都需要(通道 1 OP_READ,通道 2 OP_READ | OP_WRITE)?

当你有东西要写到频道时,就写吧

在代码的哪一部分?

如果该写入返回零,则为 OP_WRITE 注册通道,保存您尝试写入的 ByteBuffer,然后返回选择循环 当 OP_WRITE 在通道上触发时,使用相同的缓冲区调用 write() 如果写入成功并且不返回零,请再次注册 OP_READ,或者至少从 interestOps 中删除 OP_WRITE。

“如果该写入返回零”,据我所知,这意味着没有要写入的字节,那么我为什么要注册 OP_WRITE?

“保存字节缓冲区”:把这个缓冲区作为寄存器的第三个参数是真的吗?像下面这样的?

  channel.register(selector, operations, SharedBuffer);

【问题讨论】:

  • 对被引用的文本使用引号格式。

标签: java nio


【解决方案1】:

写入过程应该用填充另一个线程的字节缓冲区触发

为什么?另一个线程可以进行实际的写入。你不需要“触发”任何东西。

系统必须意识到写入或读取操作,因为它们中的任何一个都可能首先发生。

没问题。

一种防止无用cpu运行的方法,似乎OP_write在不需要时使其忙碌。

正确。 OP_WRITE 几乎总是准备就绪,因此当您没有待写入的数据时使用它已经失败只会消耗 CPU。

那么我们是只需要一个带有 OP_READ 操作数的通道还是两者都需要(通道 1 OP_READ,通道 2 OP_READ | OP_WRITE)?

您只需要一个频道。

在代码的哪一部分?

在知道它有东西要写的部分。

“如果该写入返回零”,据我所知,这意味着没有要写入的字节,

不,它没有。请参阅 Javadoc。这意味着什么都没有。如果没有“要写入的字节”,您一开始就不会调用 write()

那我为什么要注册 OP_WRITE?

所以当通道变为可写时,你可以被告知。

“保存字节缓冲区”:把这个缓冲区作为寄存器的第三个参数是真的吗?像下面这样的?

是的。

【讨论】:

  • 感谢您的患者。看来这至少是您第三次解释同一件事了。我在想没有你的 JAVA NIO ...
  • 实际上是第 3,00 个。
  • 对不起,我问你这个问题,但由于蔚来汽车有一些黑暗的部分,你为什么不写一本关于这个主题的书?我个人已经阅读了 2 本书(当然不是整本书,而是相对的部分)。但他们没有给我他们必须给的东西。
猜你喜欢
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2014-01-12
相关资源
最近更新 更多