Java的NIO编程-Selector

0x1 监控

通道和选择器之间的关系,通过register(注册)的方式完成。调用通道的Channel.register(Selector sel, int ops)方法,可以将通道实例注册到一个选择器中。register方法有两个参数:第一个参数,指定通道注册到的选择器实例;第二个参数,指定选择器要监控的IO事件类型

IO事件类型有:

  • 可读:SelectionKey.OP_READ
  • 可写:SelectionKey.OP_WRITE
  • 连接:SelectionKey.OP_CONNECT
  • 接收:SelectionKey.OP_ACCEPT

如果一下要监控多个事件的话可以用位或运算符来实现

int key = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

0x2 SelectionKey选择键

选择键的功能是很强大的。通过SelectionKey选择键,不仅仅可以获得通道的IO事件类型,比方说SelectionKey.OP_READ;还可以获得发生IO事件所在的通道;另外,也可以获得选出选择键的选择器实例

常用方法

  • isAcceptable():判断IO事件类型是否是SelectionKey.OP_ACCEPT
  • isReadable():判断IO事件是否是SelectionKey.OP_READ
  • isConnectable():判断IO事件是否是SelectionKey.OP_CONNECT
  • isWritable():判断IO事件是否是SelectionKey.OP_WRITE

0x3 使用条件

并不是所有的Channel都可以使用Selector,判断一个通道能否被选择器监控或选择,有一个前提:判断它是否继承了抽象类SelectableChannel(可选择通道)。如果继承了SelectableChannel,则可以被选择,否则不能。

简单地说,一条通道若能被选择,必须继承SelectableChannel类。

FileChannel就没有继承SelectableChannel类,所以不能使用Selector

0x4 使用流程

使用选择器,主要有以下三步:

  1. 获取选择器实例;
  2. 将通道注册到选择器中;
  3. 轮询感兴趣的IO就绪事件(选择键集合)。

0x5 Demo

源码地址: https://github.com/GreyCode9/nio-demo/tree/main/src/io/selector