问题的一般概要是具有多线程的ClientSocketChannel使用比预期更多的CPU。 一般的是具有多线程的ClientSocketChannel。 好的,我应该说我之前要问的问题是在问之前 this question
还有其他帖子有相同的答案。我再次提到的原因是我真的无法理解答案,因为它不明显,我不能用它们来采用我的代码。我试着简要解释一下这个要求,看看是否有一个可以涵盖整个要求的答案。
解答:
使用OP_WRITE的正确方法如下:
仅为OP_READ注册新接受的频道
那么我们只需要一个带OP_READ操作数的通道或两者(channel1 OP_READ,channel2 OP_READ | OP_WRITE)?
如果您有要写入频道的内容,请将其写入
代码的哪一部分?
如果该写操作返回零,则为OP_WRITE注册通道,保存您尝试写入的ByteBuffer,然后返回到选择循环 当OP_WRITE在通道上触发时,使用相同的缓冲区调用write() 如果该写入成功且未返回零,则再次注册OP_READ,或者至少从interestOps中删除OP_WRITE。
“如果该写入返回零”据我所知,这意味着没有要写入的字节,那么我为什么要注册OP_WRITE?
“保存字节缓冲区”:将此缓冲区作为寄存器的第三个参数是真的吗?像下面这样的东西?
channel.register(selector, operations, SharedBuffer);
答案 0 :(得分:1)
写入过程应该用bytebuffer触发,填充另一个线程
为什么呢?另一个线程可以进行实际写入。你不需要“触发”任何东西。
系统必须意识到写入或读取操作,因为它们中的任何一个都可能首先发生。
没问题。
一种防止无用的cpu运行的方法,似乎OP_write在不需要时使其忙碌。
正确。 OP_WRITE几乎总是准备就绪,所以当你没有待处理数据来编写已经失败的时,使用它只会吸引CPU。
那么我们只需要一个带OP_READ操作数的通道或两者(channel1 OP_READ,channel2 OP_READ | OP_WRITE)?
您只需要一个频道。
代码的哪一部分?
在知道它的部分有写东西。
“如果该写入返回零”据我所知,它意味着没有要写的字节,
不,不。见Javadoc。这意味着什么都没有写。如果“没有要写的字节”,你就不会首先调用write()
。
那我为什么要注册OP_WRITE?
因此,当频道变得可写时,您可以被告知。
“保存字节缓冲区”:将此缓冲区作为寄存器的第三个参数是真的吗?像下面这样的东西?
是