Java NIO Selector

1,SelectionKey

1)创建SelectionKey
每次channel向selector注册时,会创建一个SelectionKey。
ssc.register(selector, SelectionKey.OP_ACCEPT);
1.放入Channel的SelectionKey[]数组keys中
2.放入Selector的Set集合keys中
2)合法的ops

image.png

3)SelectionKey包含一个selector和一个channel
selector()方法获取Selector、channel()方法获取Channel
image.png

2,Channel向Selector注册过程

1)注册步骤如下

image.png

非该channel支持的valid-operation,抛出异常。如: ServerSocketChannel只支持SelectionKey.OP_ACCEPT
2)Channel有一个SelectionKey[] keys的数组
注册成功后,将返回的SelectionKey放入channel的keys数组中。
image.png

3)Selector有一个Set keys集合
注册成功后,epoll模型将SelectionKey放入selector的keys集合中。

3,Channel有效的ops集合

1)DatagramChannel支持读、写事件。

image.png

ServerSocketChannel只支持OP_ACCEPT监听事件。
image.png

SocketChannel支持读、写、连接事件。
image.png

3,Selector结构

1)三个SelectionKey的集合

image.png

image.png

2)基于OS的SelectorProvider
1. 在openjdk中,每个操作系统都有一个sun.nio.ch.DefaultSelectorProvider实现。
2. 在Linux上是EPollSelectorProvider ,在Mac OS是KQueueSelectorProvider。
3.通过EpollSelectorProvider.openSelector()创建EPollSelectorImpl Selector对象。
image.png

4,Linux epoll模型

1)基础概念
Selector:IO多路复用的一个封装,Linux下就是对epoll系统调用的封装。
epoll本质:将event loop交给了内核,网络数据先到内核,内核直接处理,避免系统调用和数据拷贝, 提高性能。
SelectionKey本质:对IO事件(读、写、连接、监听)的封装,保存Channel关心的事件。

image.png

2)epoll系统调用
image.png

image.png

3)selector.select方法选择就绪的I/O事件
1. EpollSelectorImpl底层调用native方法 epollWait。
2. epollWait 底层发起epoll_wait系统调用。
epoll_create:创建一个epollfd,使用红黑树存储准备就绪的事件。在EpollSelectorImpl初始化时调用。
epoll_ctl: 对新旧事件进行新增修改或者删除。
epoll_wait:等待内核返回I/O事件。调用Selector.select方法时底层调用。
4)NIO的select方法
selector.select()-->底层epoll_wait-->获取Iterator-->遍历处理每一个IO事件SelectionKey。
image.png

你可能感兴趣的:(Java NIO Selector)