Netty分布式NioEventLoop任务队列执行的方法
导读:本文共5203.5字符,通常情况下阅读需要17分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 执行任务队列继续回到NioEventLoop的run()方法:protectedvoidrun(){for(;;){try{switch(selectStrategy.calculateStrategy(selectNowSupplier,hasTasks())){caseSelectStrategy.CONTINUE:continue;caseSe... ...
目录
(为您整理了一些要点),点击可以直达。继续回到NioEventLoop的run()方法:
我们看到处理完轮询到的key之后,首先记录下耗时,然后通过runAllTasks(ioTime * (100 - ioRatio) / ioRatio)执行taskQueue中的任务
我们知道ioRatio默认是50,所以执行完ioTime * (100 - ioRatio) / ioRatio后,方法传入的值为ioTime,也就是processSelectedKeys()的执行时间:
首先会执行fetchFromScheduledTaskQueue()这个方法,这个方法的意思是从定时任务队列中聚合任务,也就是将定时任务中找到可以执行的任务添加到taskQueue中
longnanoTime = AbstractScheduledEventExecutor.nanoTime()代表从定时任务初始化到现在过去了多长时间
Runnable scheduledTask= pollScheduledTask(nanoTime)代表从定时任务队列中拿到小于nanoTime时间的任务,因为小于初始化到现在的时间,说明该任务需要执行了
跟到其父类AbstractScheduledEventExecutor的pollScheduledTask(nanoTime)方法中:
我们看到首先获得当前类绑定的定时任务队列的成员变量
如果不为空,则通过scheduledTaskQueue.peek()弹出第一个任务
如果当前任务小于传来的时间,说明该任务需要执行,则从定时任务队列中删除
我们继续回到fetchFromScheduledTaskQueue()方法中:
弹出需要执行的定时任务之后,我们通过taskQueue.offer(scheduledTask)添加到taskQueue中,如果添加失败,则通过scheduledTaskQueue().add((ScheduledFutureTask<?>) scheduledTask)重新添加到定时任务队列中
如果添加成功,则通过pollScheduledTask(nanoTime)方法继续添加,直到没有需要执行的任务
这样就将定时任务队列需要执行的任务添加到了taskQueue中
首先通过Runnable task = pollTask()从taskQueue中拿一个任务
任务不为空,则通过finallongdeadline = ScheduledFutureTask.nanoTime() + timeoutNanos计算一个截止时间,任务的执行时间不能超过这个时间
然后在for循环中通过safeExecute(task)执行task
我们跟到safeExecute(task)中:
这里直接调用task的run()方法进行执行,其中发生异常,只打印一条日志,代表发生异常不终止,继续往下执行
回到runAllTasks(long timeoutNanos)方法:
每次执行完task, runTasks自增
这里if((runTasks & 0x3F) == 0)代表是否执行了64个任务,如果执行了64个任务,则会通过lastExecutionTime = ScheduledFutureTask.nanoTime()记录定时任务初始化到现在的时间,如果这个时间超过了截止时间,则退出循环
如果没有超过截止时间,则通过task = pollTask()继续弹出任务执行
这里执行64个任务统计一次时间,而不是每次执行任务都统计,主要原因是因为获取系统时间是个比较耗时的操作,这里是netty的一种优化方式
如果没有task需要执行,则通过afterRunningAllTasks()做收尾工作,最后记录下最后的执行时间
Netty分布式NioEventLoop任务队列执行的方法的详细内容,希望对您有所帮助,信息来源于网络。