原创文章:Selector选择器 – 编程屋
1 基本介绍
-
java中的nio,用非阻塞的IO方式。可以用一个线程,处理多个客户端连接,就会使用到Selector选择器
-
Selector能够检测多个注册的通道上是否有事件发生(注意:多个Channle以事件的方式可以注册到同一个Selector),如果有事件发生获取事件然后针对每个事件进行相应的处理,这样就可以用一个单线程管理多个通道,也就是管理多个连接和请求。
-
只有在连接有多个读写事件发生时,才会进行读写,就大大减少了系统的开销,并且不会为每个连接都创建一个线程,不用去维护多个线程
-
避免了多线程之间上下文切换导致的开销。
特点说明:
-
Netty的IO线程NioEventLoop聚合了Selector选择器,也叫多路复用器,可以同时处理成百上千条请求。当线程从某客户端Socket通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务
-
线程通常将非阻塞的IO的空闲线程用在其它通道执行IO操作,所以单独的线程可以管理多个输入和输出通道
-
由于读写操作都是非阻塞的,这就可以充分提升IO线程的运行效率,避免由于频繁I/O阻塞导致线程挂起
-
一个I/O线程可以并发处理N个客户端连接和读写数据操作,这从根本上解决了传统同步阻塞I/O一连接一线程模型。
2 使用方法
1.通过调用Selector.open()方法创建一个Selector对象
Selector open = Selector.open();
2.注册channel到Selector
socketChannel.configureBlocking(false);
final SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ);
注意:注册的channel必须是非阻塞的(FileChannel不适用于Selector,因为FileChannel不能切换为非阻塞模式)
register()方法的第二个参数,是通过Selector监听Channel对什么事件感兴趣
Connect : 某个 Channel 成功连接到另一个服务器称为"连接就绪", SelectionKey.OP_CONNECT
Accept : 一个 ServerSocketChannel 准备好接受新进入的连接称为"接受就绪", SelectionKey.OP_ACCEPT
Read : 一个有数据可读的 Channel 称为"读就绪", SelectionKey.OP_READ
Write : 等待写数据的 Channel 称为"写就绪", SelectionKey.OP_WRITE
如果不止对一件事情感兴趣,可以用操作符将其连接起来如下:
SelectionKey key = channel.register(selector,Selectionkey.OP_READ|SelectionKey.OP_WRITE);
总结:
以上只是部分内容,为了维护方便,本文已迁移到新地址:Selector选择器 – 编程屋