目录
- NioEventLoop.execute()
 - addTask()
 - startThread()
 - NioEventLoop.run()
 - select()
 - 处理keys与执行任务
 - processSelectedKeys()
 - 处理AbstractNioChannel
 - selectAgain()
 
- runAllTasks()
 - fetchFromScheduledTaskQueue()
 - runAllTasksFrom()
 - afterRunningAllTasks()
 
- 带截止时间的runAllTasks()
 - unexpectedSelectorWakeup()
 - rebuildSelector0()
 
NioEventLoop.execute()
在前一篇多次看到向eventloop中提交任务,本篇就分析该方法的源码过程。

在这个过程中最关键的是两步:
- 将task添加到taskQueue中的
addTask()方法 - 启动任务线程
startThread() 
addTask()

startThread()

startThread()中主要是向NioEventLoop的executor中提交一个任务,当获得线程资源之后调用NioEventLoop的run()方法。
NioEventLoop.run()

run()中主要是一个死循环,该循环不断执行三个过程:
- 调用
select()方法获取已经就绪的channel并将channel对应的key存放到NioEventLoop的selectionKeys中 - 处理
selectionKeys中的key,执行任务队列taskQueue中的任务 - 记录select的次数,如果空轮询次数过多或者出现异常情况则重新建立selector
 
select()

处理keys与执行任务
在这里通过ioRatio来平衡IO事件与非IO事件的处理时间。
 
processSelectedKeys()

处理AbstractNioChannel

selectAgain()

runAllTasks()
runAllTasks()分两种情况,一种是不限制处理时间,一种是限制处理时间的。
 
fetchFromScheduledTaskQueue()

runAllTasksFrom()

afterRunningAllTasks()

带截止时间的runAllTasks()
带截止时间的runAllTasks()过程如下,如果处理tasks的时间超时则停止处理。
 
unexpectedSelectorWakeup()
Netty为了解决空轮询bug在run()方法中设立了一个selectCnt变量,每执行一次selectCnt+1,当空轮询达到512次时建立一个新的selector。

rebuildSelector0()

最后总结一下整个execute()的过程。

至此,NioEventLoop.execute()的过程分析至此结束,感谢阅读。
 

![[数据结构 -- C语言] 栈(Stack)](https://img-blog.csdnimg.cn/img_convert/269e8d78fcd347b39d32a09c206d46a5.png)
















