Java NIO – 使用选择器

有一些关于使用非阻塞选择器的快速问题 – 回答下面的任何一个将不胜感激:

我刚刚学习了选择器(java NIO模型),并希望澄清一些事实。 从教程和SO问题中挑选了大部分关键点: Java NIO:选择器

所以:

  1. 从上面链接的问题中,注册服务器套接字通道以监听接受,当接受通道注册读取时,一旦读取它就注册为写入。 然后如何重新听取接受? 我的意思是似乎没有重复调用寄存器接受监听器。 只是一旦注册了ServerSocketChannel,选择器将始终监听接受吗? 如果是这样,这是否意味着选择器将始终监听通道上的读/写? 你如何阻止它 – 它是否像关闭频道一样简单?

  2. 如果频道注册两次会怎样? 我的意思是 – 在上面的例子中,每次读取一条消息后都会注册一个套接字 – 基本上看起来像一个echo服务器。 我想这个例子假设在写完后连接将被关闭。 如果你想保持一个开放的连接并以不同的间隔写入套接字会发生什么 – 你必须每次都注册一个interestOp吗? 两次注册同一频道是否有害?

  3. multithreading:现在编写multithreading服务器的最佳设计是什么 – 因为上面的非阻塞方法假定一个线程可以处理写入和读取。 如果预期读/写操作需要一段时间,您是否应该创建新线程? 还有其他要考虑的问题吗?

了解multithreading是用于阻止IO但是已经看到一些使用线程池和非阻塞模型的框架,并且想知道为什么。

注册服务器套接字通道以监听接受,当接受通道注册读取时,一旦读取它就注册为写入。 然后如何重新听取接受?

它不必“回去”。 它正在倾听。 它已注册。 什么也没有变。

如果频道注册两次会怎样?

interestOps已更新,之前的密钥附件将丢失。

我的意思是 – 在上面的例子中,每次读取一条消息后都会注册一个套接字进行写操作。

这是一个非常糟糕的例子。 技术不正确。 你应该写。 如果write()返回零, 那么你应该(a)为OP_WRITE;注册通道OP_WRITE; (b)当频道变为可写时重试写入; (c)一旦写入完成,取消注册OP_WRITE的通道。

我想这假设连接将在写入后关闭。

我不明白为什么。 它不遵循。 无论如何,这是一个糟糕的例子,不被模仿。 你最好在这里模仿答案 ,而不是没有答案的问题。

如果你想保持一个开放的连接并以不同的间隔写入套接字会发生什么 – 你必须每次都注册一个interestOp吗? 两次注册同一频道是否有害?

往上看。 保持频道畅通。 除非你改变它们,否则它的interestOps不会改变; 你应该像上面那样处理写作,而不是你所引用的不好的例子。

multithreading:现在编写multithreading服务器的最佳设计是什么 – 因为上面的非阻塞方法假定一个线程可以处理写入和读取。

如果您想要multithreading,请使用阻塞I / O,最简单的方法是通过java.net. 如果您想要非阻塞I / O,则不需要multithreading。 我不明白为什么你在同一个问题上问两个问题。

如果预期读/写操作需要一段时间,您是否应该创建新线程?

在最常见的阻塞I / O的情况下,每个连接有两个线程:一个用于读取,一个用于写入。