Nio基于 Reactor(反应器)模式。
需要先了解Reactor!
Liunx 对Reactor IO 设计的支持是Epoll
EPollArrayWrapper的核心要点如下:
1: EPollArrayWrapper 是JAVA 对Epoll的封装(不是重新实现)
2: "真正" select() 是 EPollArrayWrapper实现的(也就是Nio中的IO感知)
3: EPollArrayWrapper 在封装Epoll 同时支持了JAVA的中断机制
这里我们需要先理解Linux Epoll是什么个功能 是怎么设计的(一切皆文件,这个概念很重要)
如果还不了解的: www.cnblogs.com/DarkH/archi...

epoll_event是事件(为了屏蔽C与JAVA的不同 统一称为enent) epoll_data 如果熟悉lambda的同学就可以把它想象成callback epoll 是不会解它的,怎么进来的就怎么回去


上述需要着重关注的属性如果下:
outgoingInterruptFD
incomingInterruptFD
interruptedIndex
这三个字段是NIO 中断支持的关键字段
Nio是怎么设计支持的呢
答案是: 模拟IO行为 使用特殊的管道
Nio 会创建了一个无名管道,并返回一个长整数(long),该整数实际上编码了两个文件描述符。 无名管道在UNIX和Linux系统中是一个很基本的IPC(进程间通信)机制,它提供了两个文件描述符:一个用于读,另一个用于写。 fd0通常是读端。 fd1通常是写端。
Reactor模式只有一条BOSS线程负责和Epoll交互 它也只干这件事。 那么Epoll阻塞的线程 也只会是它 当这条Boss总线感到IO事件发生了(Epoll通知的), 它会检查是否中断管道发生的 如果是 那么Boss线程就知道要中断自己了!
outgoingInterruptFD就是外部写信息的端口。 incomingInterruptFD就是内部检查(EPollArrayWrapper )的端口.interruptedIndex只是确定事件位置。

updated 已经就绪的IO数量
updateCount 已经注册需要改变fd的数量(fd) 这里改变不是fd 而是fd关心的事件
updateDescriptors 装fd的数组(因为fd是一个int 那么add和find 都是O(n))
eventsLow 这里需要着重理解下 fd是个int 那么eventsLowA 那么就是A fd,而 value是此fd感兴趣的event


上述这些都是基础方法 是操作fd和 对应event的存取的

注意理解 (b== mask) 这里考虑了位比较的情况 也就是说虽然 mask入参类型是int 都希望它是byte。那问题又来了 为什么不直接使用byte 因为java byte是有符号的 无法区分-1 和 255

核心方法:

处理已注册的fd更新申请。 一定要理解 预存 也就是处理时机 不是你注册申请Nio 就会马上给你处理 它是必须等待下一轮epollwait的结束后一次性处理!!

Poll()是配合Reactor模式设计的 只有BOSS线程调用poll 也只需要只干这件事
ini
if (getDescriptor(i) == incomingInterruptFD) {
interruptedIndex = i;
interrupted = true;
break;
}
检查此次IO事情是否为中断线程如果是就打上interrupted!
我们最后看看JNI_C的实现
