目录
- 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()
的过程分析至此结束,感谢阅读。