NioEventLoop启动流程源码解析 (6)

聚合任务就是把已经到执行时间的任务从定时任务队列中全部取出 ,放入普通任务队列然后执行, 我们进入上的第一个方法fetchFromScheduledTaskQueue,源码如下,

private boolean fetchFromScheduledTaskQueue() { // todo 拉取第一个聚合任务 long nanoTime = AbstractScheduledEventExecutor.nanoTime(); // todo 从任务丢列中取出 截止时间是 nanoTime的定时任务 , // todo 往定时队列中添加 ScheduledFutureTask任务, 排序的基准是 ScheduledFutureTask 的compare方法,按照时间,从小到大 // todo 于是当我们发现队列中的第一个任务,也就是截止时间最近的任务的截止时间比我们的 Runnable scheduledTask = pollScheduledTask(nanoTime); while (scheduledTask != null) { // todo scheduledTask != null表示定时任务该被执行了, 于是将定时任务添加到 普通任务队列 if (!taskQueue.offer(scheduledTask)) { // No space left in the task queue add it back to the scheduledTaskQueue so we pick it up again. // todo 如果添加失败了, 把这个任务从新放入到定时任务队列中, 再尝试添加 scheduledTaskQueue().add((ScheduledFutureTask<?>) scheduledTask); return false; } // todo 循环,尝试拉取定时任务 , 循环结束后,所有的任务全部会被添加到 task里面 scheduledTask = pollScheduledTask(nanoTime); } return true; }

根据指定的截止时间,从定时任务队列中取出任务,定时任务队列中任务按照时间排序,时间越短的,排在前面, 时间相同,按照添加的顺序排序, 现在的任务就是检查定时任务队列中任务,尝试把里面的任务挨个取出来,于是netty使用这个方法Runnable scheduledTask = pollScheduledTask(nanoTime); 然后马上在while(){}循环中判断是否存在, 这个方法实现源码如下, 不难看出,他是在根据时间判断

/** * Return the {@link Runnable} which is ready to be executed with the given {@code nanoTime}. * You should use {@link #nanoTime()} to retrieve the the correct {@code nanoTime}. * todo 根据给定的纳秒值,返回 Runable定时任务 , 并且,每次使用都要冲洗使用是nanoTime() 来矫正时间 */ protected final Runnable pollScheduledTask(long nanoTime) { assert inEventLoop(); Queue<ScheduledFutureTask<?>> scheduledTaskQueue = this.scheduledTaskQueue; ScheduledFutureTask<?> scheduledTask = scheduledTaskQueue == null ? null : scheduledTaskQueue.peek(); if (scheduledTask == null) { return null; } // todo 如果定时任务的截止时间<= 我们穿进来的时间, 就把他返回 if (scheduledTask.deadlineNanos() <= nanoTime) { scheduledTaskQueue.remove(); return scheduledTask; } // todo 否则返回kong,表示当前所有的定时任务都没到期, 没有可以执行的 return null; }

经过循环之后,到期的任务,全被添加到 taskQueue里面了,下面就是执行TaskQueue里面的任务

任务队列中的任务是怎么执行的?

safeExecute(task); 方法,执行任务队列中的任务
源码如下: 实际上就行执行了 task这个Runable的Run方法

/** * Try to execute the given {@link Runnable} and just log if it throws a {@link Throwable}. */ protected static void safeExecute(Runnable task) { try { task.run(); } catch (Throwable t) { logger.warn("A task raised an exception. Task: {}", task, t); } }

Nio网络编程模型

总结一下: 到现在为止,EventLoop已经启动了, 一说到NioEventLoop总是想起上图, 现在他可以接受新的连接接入,轮询,处理任务...

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxwxs.html