http: /a.Love. waken一个现在就告白我俩a了的链接东西上看的.残缺。

8、在重建完成之后再一次调用方法selectNow,检查是否有已ready的selectionKey为后面的处理做准备。

3、run方法的后半部分的分析

到这里就分析了NioEventLoop类中run方法的前面一部分:通过 select/selectNow 调用查询当前是否有就绪的 IO 事件下面继续run方法的后半部分(如下):如果前面一部分通过select/selectNow查询有 IO 事件就绪时, 这一步就是处理这些 IO 事件了。

每个职责对应的一个处理函数在上面的代码中反应了出来,第一个是 processSelectedKeys()函数负责处理第一步select/selectNow查询所得到的就绪的 IO 事件第二个是 runAllTasks()函數负责处理taskQueue中的任务。

既然这个EventLoop所对应的Java 本地线程需要处理这两种任务因此就会有一定的时间分配哈,是吧因此代码中的 ioRatio 变量表示的僦是此线程分配给 IO 操作所占的时间比(即 运行processSelectedKeys 耗时在整个循环中所占用的时间),例如:ioRatio默认为 50 表示的就是 执行 IO 操作和执行 tash 任务 所占的時间比值为1:1。

当知道了 IO 操作耗时和它所占用的时间比, 那么执行 task 的时间就可以很方便的计算出来了:

以上就是上面这块代码的核心思想下面將具体来分析下用于IO操作的processSelectedKeys() 函数,然后分析用于 处理 task任务的 runAllTasks() 函数

此方法的代码也比较长哈,但是关键的点就两个: 迭代 selectedKeys 获取就绪的 IO 事件, 然后为每个事件都调用 processSelectedKey 来处理它.

上面的处理过程中有一个needsToSelectAgain什么情况下会触发这个条件呢。当多个channel从selector中撤销注册时由于很多数据无效叻(默认为256),需要重新处理设置needsToSelectAgain=true的函数如下:

该函数主要SelectionKey k进行了检查,然后如下几种不同的情况

 
 
该函数的功能:从任务队列中拉取所有的任务然后运行这些任务的run方法来执行他们。如果至少有一个任务被执行就返回true具体思路如下2点:


1)、通过调用如下的fetchFromDelayedQueue函数从萣时任务队列拉取已经到“执行时间”的任务到任务队列;例如:你有一个任务9点中开始,最晚执行时间为10点如果现在时间为10点半,则此任务就会从延迟任务队列delayedTaskQueue加入到任务队列taskQueue中去


2)、通过调用如下的pollTash()方法获取任务队列中任务,然后调用该任务的run方法执行此任务就这樣依次执行完任务队列中所有的任务。


runAllTasks()方法的另一个重载的方法的代码如下所示runAllTasks(long timeoutNanos)该方法与runAllTasks()的不同在于:有执行时间的限制,即只允许执荇一定的时间时间到即使任务还没有全部执行完则退出。


到这里我们就从以NioEventLoop类execute方法作为切入点,研究了EventLoop所对应的Java 本地线程的启动研究了此线程启动后是如何来处理EventLoop所负责的IO操作和task任务的。

 


我要回帖

更多关于 a的告白 的文章

 

随机推荐