一、Java NIO Selector 基本介绍
Java的NIO,用非阻塞的IO方式。可以用一个线程,处理多个的客户端连接,就会使用到Selector(选择器)。Selector能够检测多个注册的通道上是否有事件发生(注意:多个Channel以事件的方式可以注册到同一个Selector),如果有事件发生,便获取事件然后针对每个事件进行相应的处理。这样就可以只用一个单线程去管理多个通道,也就是管理多个连接和请求。- 只有在连接/通道真正有读写事件发生时,才会进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程。
- 避免了多线程之间的上下文切换导致的开销
二、Java NIO Selector 示意图和特点说明

说明如下:
**Netty**的**IO**线程**NioEventLoop**聚合了**Selector**(选择器,也叫多路复用器),可以同时并发处理成百上千个客户端连接。- 当线程从某客户端
**Socket**通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。 - 线程通常将非阻塞
**IO**的空闲时间用于在其他通道上执行**IO**操作,所以单独的线程可以管理多个输入和输出通道。 - 由于读写操作都是非阻塞的,这就可以充分提升
**IO**线程的运行效率,避免由于频繁**I/O**阻塞导致的线程挂起。 - 一个
**I/O**线程可以并发处理**N**个客户端连接和读写操作,这从根本上解决了传统同步阻塞**I/O**一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。
三、Java NIO Selector 类相关方法

//得到一个Selector对象public static Selector open() throws IOException {return SelectorProvider.provider().openSelector();}public abstract boolean isOpen();/*** Tells whether or not this selector is open.* 判断这个选择器是否打开* @return <tt>true</tt> if, and only if, this selector is open*/public abstract boolean isOpen();/*** 监控所有的注册的通道,当其中有IO操作可以进行的时候,讲对应得到SelectionKey加入到内部集合中并返回,参数用来设置超时时间*/public abstract int select(long timeout) throws IOException;/*** Returns this selector's selected-key set.** <p> Keys may be removed from, but not directly added to, the* selected-key set. Any attempt to add an object to the key set will* cause an {@link UnsupportedOperationException} to be thrown.** <p> The selected-key set is <a href="#ksc">not thread-safe</a>. </p>** @return This selector's selected-key set** @throws ClosedSelectorException* If this selector is closed* 从内部集合中得到所有的SelectionKey*/public abstract Set<SelectionKey> selectedKeys();
其他方法:
selector.select();//阻塞selector.select(1000);//阻塞 1000 毫秒,在 1000 毫秒后返回selector.wakeup();//唤醒 selectorselector.selectNow();//不阻塞,立马返还
