Netty入门(三):EventLoop (2)

其核心就是实现了newChild方法返回一个EventLoop extends EventExecutor实例

protected EventLoop newChild(Executor executor, Object... args) throws Exception { return new DefaultEventLoop(this, executor); } 7.总结

说白了EventLoopGroup核心方法,register负责将channel与线程池中某一线程绑定,next负责返回下一个线程供调用方执行任务

Netty入门(三):EventLoop

EventLoop

EventLoop直译为事件循环,他的职责简单来说就是绑定一个唯一的线程,去执行或调度被分配的任务。

可见一个EventLoop实例可以为多个channel服务,而为了最大化利用资源,Netty使用池化技术将EventLoop放入EventLoopGroup中管理。

EventLoop的具体实现有很多,先看下DefaultEventLoop的类图,会发现他和DefaultEventLoopGroup的类图很像,都继承了EventLoopGroup接口,但其最大的不同是红框所示,他还继承了EventExecutor,下面主要讲一下多出来的这部分到底是干了什么

Netty入门(三):EventLoop

 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 EventLoop

 EventLoop的抽象基类,负责在单线程中执行所有被提交的任务,同时具有注册和处理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.
机不可失,时不我待。

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

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