其核心就是实现了newChild方法返回一个EventLoop extends EventExecutor实例
protected EventLoop newChild(Executor executor, Object... args) throws Exception { return new DefaultEventLoop(this, executor); } 7.总结说白了EventLoopGroup核心方法,register负责将channel与线程池中某一线程绑定,next负责返回下一个线程供调用方执行任务
EventLoopEventLoop直译为事件循环,他的职责简单来说就是绑定一个唯一的线程,去执行或调度被分配的任务。
可见一个EventLoop实例可以为多个channel服务,而为了最大化利用资源,Netty使用池化技术将EventLoop放入EventLoopGroup中管理。
EventLoop的具体实现有很多,先看下DefaultEventLoop的类图,会发现他和DefaultEventLoopGroup的类图很像,都继承了EventLoopGroup接口,但其最大的不同是红框所示,他还继承了EventExecutor,下面主要讲一下多出来的这部分到底是干了什么
1.EventExecutor接口,定义了一个事件执行器,主要方法如下
/** * 直接返回自身 */ @Override EventExecutor next(); /** * 返回所属线程池 */ EventExecutorGroup parent(); /** * 判断当前线程是否是当前EventLoop绑定的线程 */ boolean inEventLoop(); /** * 判断传入线程是否是当前EventLoop绑定的线程 */ boolean inEventLoop(Thread thread);(还涉及一些Future异步编程的一些东西,太复杂了后续再填坑吧0.0)
2.AbstractScheduledEventExecutor (AbstractEventExecutor)抽象类,简单定义了一个支持延迟(定时)任务的执行器
//延时队列 PriorityQueue<ScheduledFutureTask<?>> scheduledTaskQueue; //下一个任务id long nextTaskId;重要方法scheduled
private <V> ScheduledFuture<V> schedule(final ScheduledFutureTask<V> task) { if (inEventLoop()) { //如果和执行器绑定的线程一致,直接放入延时队列中 scheduleFromEventLoop(task); } else { //获取任务最晚执行时间 final long deadlineNanos = task.deadlineNanos(); // task will add itself to scheduled task queue when run if not expired if (beforeScheduledTaskSubmitted(deadlineNanos)) { //放入线程池执行 execute(task); } else { //与execute类似,但不保证任务会在执行非延迟任务或执行程序关闭之前运行,默认实现只是委托给execute(Runnable) lazyExecute(task); // Second hook after scheduling to facilitate race-avoidance if (afterScheduledTaskSubmitted(deadlineNanos)) { execute(WAKEUP_TASK); } } } return task; } 3.SingleThreadEventExecutor抽象类,定义了一个单线程顺序执行器
private void execute(Runnable task, boolean immediate) { boolean inEventLoop = inEventLoop(); //添加到任务队列 addTask(task); if (!inEventLoop) { //启动线程 startThread(); //如果线程池已经关闭,调用拒绝方法 if (isShutdown()) { boolean reject = false; try { if (removeTask(task)) { reject = true; } } catch (UnsupportedOperationException e) { // The task queue does not support removal so the best thing we can do is to just move on and // hope we will be able to pick-up the task before its completely terminated. // In worst case we will log on termination. } if (reject) { reject(); } } } //唤醒线程 if (!addTaskWakesUp && immediate) { wakeup(inEventLoop); } } 4.SingleThreadEventLoop public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoopEventLoop的抽象基类,负责在单线程中执行所有被提交的任务,同时具有注册和处理channle的能力
5.DefaultEventLoop单线程任务执行器的默认实现,主要就是其实现的run方法
protected void run() { //循环阻塞的获取任务,知道被通知关闭 for (;;) { Runnable task = takeTask(); if (task != null) { task.run(); updateLastExecutionTime(); } if (confirmShutdown()) { break; } } } 6.总结通过以上分析,不难看出Netty首先定义了自己的线程池(EventExectorGroup)和执行器(EventExector),然后通过继承的方式定义了线程池(EventLoopGroup)和执行器(EventLoop),从而添加了处理(注册)channel的能力。
You gotta grab what you can when you can.
机不可失,时不我待。