IV . SelectionKey 简介
SelectionKey 简介 :
① SelectionKey 作用 : SelectorImpl 是 Selector 的实现类 , 在其中可以看到很多 SelectionKey 的 Set 集合 ;
② SelectionKey 集合 : 存储有事件发生的 通道 ( Channel ) 对应的 SelectionKey ;
public abstract class SelectorImpl extends AbstractSelector { protected Set<SelectionKey> selectedKeys = new HashSet(); protected HashSet<SelectionKey> keys = new HashSet(); private Set<SelectionKey> publicKeys; private Set<SelectionKey> publicSelectedKeys;
...
③ 通道 注册给 选择器 : 通道 ( Channel ) 注册到 选择器 ( Selector ) 中 , 每个 通道 ( Channel ) 都有一个对应的 SelectionKey ;
④ 事件触发机制 : 选择器 ( Selector ) 监控到某通道有事件发生 , 就会拿到该通道对应发生的事件的 个数 , 之后处理事件时 , 再去遍历 SelectionKey 集合 , 通过 SelectionKey 可以获取对应的 通道 ( Channel ) , 线程开始为该 通道 ( Channel ) 进行服务 ;
⑤ 通过 SelectionKey 获取 通道 ( Channel ) : 在 SelectionKey 中定义了获取 通道 的方法 , 可以直接获取对应的通道 ;
public abstract SelectableChannel channel()
⑥ 获取触发事件的通道 : 调用 选择器 ( Selector ) 的 select() 方法 , 就可以获得有几个 通道 ( Channel ) 中有事件发生 , 将有事件发生的 通道 的 SelectionKey 放入到集合中 ;
⑦ 触发的事件 : 上述集合中每个 SelectionKey 都代表一个对应 通道 ( Channel ) 的事件 , 如 : 客户端 TCP 连接 , 读取数据 , 写出数据 等事件 ;
V . 选择器 ( Selector ) 工作流程
1 . 创建通道 : 服务器端 , 每当有客户端连接服务器时 , 服务器的 ServerSocketChannel 就会创建一个与客户端对应的 SocketChannel ;
2 . 注册通道 : 将创建的 SocketChannel 注册给 选择器 ( Selector ) , 调用通道的 register() 方法将 通道 ( Channel ) 注册给选择器 ( Selector ) ;
① 注册对应关系 : 一个 选择器 ( Selector ) 可以注册多个 通道 ( Channel ) ;
② 注册返回值 : 通道 注册给 选择器 后 , 会返回 SelectionKey , 此时将 SelectionKey 放入 选择器 ( Selector ) 的集合中进行管理 , 调用 选择器的 keys() 方法 , 可以获取这些注册的 SelectionKey 的 Set 集合 ;
③ 常用的注册方法 : ops 指的是关注的事件 ;
SelectionKey register(Selector sel, int ops) SelectionKey register(Selector sel, int ops, Object att)
3 . 选择器 ( Selector ) 开始监听 : 调用 select() , select(long timeout) , selectNow() 方法 , 以 阻塞或非阻塞 的方式获取其管理的通道中 , 有几个通道触发了事件 ;
事件的种类 :
OP_READ : 读取数据事件 ;
OP_WRITE : 写出数据事件 ;
OP_CONNECT : 连接操作事件 ;
OP_ACCEPT : 等待连接操作事件 ;
4 . 获取 SelectionKey : 获取有事件发生的 通道 ( Channel ) 的 SelectionKey ;
5 . 获取 SelectionKey 对应的通道 : 调用 SelectionKey 的 channel() 方法 , 可以获取 SelectionKey 对应的 通道 ( Channel ) ;
6 . 通道 ( Channel ) 处理 : 执行真正的业务处理流程 ;