NIO this.selector.select
过程梳理:
1. SelectorImpl.lockAndDoSelect()
2. windowsSelectorImpl.doSelect 正式开始轮询事件
2.1 subSelector.poll(); 开始底层的轮询,获取就绪文件描述符
2.2 this.updateSelectedKeys(); 将就绪的key加入到selectedKeys中,进入该方法
2.2.1 this.subSelector.processSelectedKeys(this.updateCount);在主线程调用poll之后,会获取到已就绪的文件描述符(包含可读、可写、异常)。通过调用processSelectedKeys将就绪的文件描述符对应的SelectorKey加入到selectedKeys中。这样我们外部就可以调用到所有就绪的SelectorKey进行遍历处理。
SelectorImpl.lockAndDoSelect()
重点:最后执行SelectorImpl.doSelect,在windows平台由WindowsSelectorImpl实现
WindowsSelectorImpl#doSelect
一个个来分析
protected int doSelect(long var1) throws IOException {
//首先查看Selector中是否有Channel,没有就抛出异常
if (this.channelArray == null) {
throw new ClosedSelectorException();
} else {
this.timeout = var1;
this.processDeregisterQueue();
设置中断器,实际调用的是AbstractSelector.this.wakeup();方法
// 调用的是方法AbstractInterruptibleChannel.blockedOn(Interruptible);
if (this.interruptTriggered) {
this.resetWakeupSocket();
return 0;
} else {
//调整辅助线程数量
this.adjustThreadsCount();
//调整主线程与辅助线程之间的运行关系
this.finishLock.reset();
this.startLock.startThreads();
try {
this.begin();
try {
//执行poll方法
this.subSelector.poll