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 使用流程
使用选择器,主要有以下三步:
- 获取选择器实例;
- 将通道注册到选择器中;
- 轮询感兴趣的IO就绪事件(选择键集合)。
0x5 Demo
源码地址: https://github.com/GreyCode9/nio-demo/tree/main/src/io/selector