文章目录
EventLoop整体
- EventLoop,字面意思来看是事件循环,内部是一个线程;Netty 是Reactor线程模型的一种实现,结合Netty 中的线程模型和 Reactor 模型来理解EventLoop 在Netty 中的作用;
- EventLoopGroup,是一组EventLoop,内部有一组EventLoop 线程
- 本文先从整体来看看:EventLoop ,主要是它的继承体系
一、上层类和接口
- 紧接上文,如下是 EventLoop 和 EventLoopGroup 的整体继承体系:
-
EventLoop 本身就继承了EventLoopGroup的方法,原因在上文也略有提到,因为EventLoopGroup 的功能是调用内部的 EventLoop实现的,因此从 API 来看 EventLoop 包含了 EventLoopGroup 的 API。我们从上到下来分析 EventLoop 的继承体系:
-
EventLoopGroup 本身提供的功能主要包括执行IO操作,包括 执行与 Channel 相关的 IO 操作,比如IO连接,读写数据等,另一个是提供线程池的任务执行功能,对应的方法是schedule,submit等。
1.1 EventExecutor
- EventExecutor 对于 EventExecutorGroup 很像 EventLoop 对于 EventLoopGroup,EventExecutor代表事件执行器,是 EventLoop 的一个上层接口
/**
* 事件执行器接口 ,特殊的 EventExecutorGroup ,能够通过方法判断 线程是否在 event loop 内部执行
* 另外,扩展了一些通用方法
* The {@link EventExecutor} is a special {@link EventExecutorGroup} which comes
* with some handy methods to see if a {@link Thread} is executed in a event loop.
* Besides this, it also extends the {@link EventExecutorGroup} to allow for a generic
* way to access methods.
*/
public interface EventExecutor extends EventExecutorGroup {
/**
* 返回自己
@Override
EventExecutor next();
/**
* 所属 EventExecutorGroup
*/
EventExecutorGroup parent();
/**
* 当前线程是否在EventLoop线程中
*
*/
boolean inEventLoop();
/**
* 指定线程是否是 EventLoop 线程
*
*/
boolean inEventLoop(Thread thread);
/**
* 创建一个 Promise 对象
*/
<V> Promise<V> newPromise();
/**
* 创建一个 ProgressivePromise 对象
*/
<V> ProgressivePromise<V> newProgressivePromise();
/**
* 创建成功结果的 Future 对象
* Create a new {@link Future} which is marked as succeeded already. So {@link Future#isSuccess()}
* will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
* every call of blocking methods will just return without blocking.
*/
<V> Future<V> newSucceededFuture(V result);
/**
* 创建异常的 Future 对象
* Create a new {@link Future} which is marked as failed already. So {@link Future#isSuccess()}
* will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
* every call of blocking methods will just return without blocking.
*/
<V> Future<V> newFailedFuture(Throwable cause);
}
1.2 OrderedEventExecutor
- OrderedEventExecutor 是一个标记接口,没有代码,表示处理任务的方式是有序的
/**
* 一个 EventExecutor 的标记接口,以有序的方式处理全部的任务
* Marker interface for {@link EventExecutor}s that will process all submitted tasks in an ordered / serial fashion.
*/
public interface OrderedEventExecutor extends EventExecutor {
}
1.3 AbstractEventExecutor
- 实现了 ExecutorService 和 EventExecutorGroup 的方法,但是很多只是空实现
/**
* EventExecutor 的抽象实现
* AbstractEventExecutor 实现了继承自 ExecutorService 和 EventExecutorGroup 的方法,但是很多方法只是空实现
* Abstract base class for {@link EventExecutor} implementations.
*/
public abstract class AbstractEventExecutor extends AbstractExecutorService implements EventExecutor {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractEventExecutor.class);
/**
* 关闭期间,该段时间内收到任务会被接受并且重新计时
*/
static final long DEFAULT_SHUTDOWN_QUIET_PERIOD = 2;
/**
* 默认关闭超时,单位:秒
*/
static final long DEFAULT_SHUTDOWN_TIMEOUT = 15;
/**
* 所属 EventExecutorGroup
*/
private final EventExecutorGroup parent;
/**
* EventExecutor 数组。只包含自己,用于 {@link #iterator()}
*/
private final Collection<EventExecutor> selfCollection = Collections.<EventExecutor>singleton(this);
//省略其他方法...
/**
* 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);
}
}
}
1.4 AbstractScheduledEventExecutor
- AbstractScheduledEventExecutor 是支持定时任务的 EventExecutor 的抽象类,主要实现了 AbstractEventExecutor 的定时任务相关方法,比如:scheduleWithFixedDelay、scheduleAtFixedRate等,
- AbstractScheduledEventExecutor 内部维护一个任务队列,具体关于 AbstractScheduledEventExecutor 细节后续在分析 EventLoop 的定时任务相关执行的时候再具体分析
1.5 SingleThreadEventExecutor
- SingleThreadEventExecutor 是基于单线程的 EventExecutor 抽象类,即一个 EventExecutor 对应一个线程,内部持有一个线程对象、拒绝策略对象、和很多关键属性,实现了大部分执行任务的方法,比如invokeAll、invokeAny、 execute、关闭等方法,内部的源码其实和线程池类似,不过内部只有一个线程;
- 后续 NioEventLoop的实现类,内部也是单线程的,业继承了 SingleThreadEventExecutor,
- SingleThreadEventExecutor 的源码非常多,放在后续分析
二、EventLoop
2.1 EventLoop
- EventLoop 本身只定义了一个parent方法,用于指定自己是属于哪一个EventLoopGroup
/**
* EventLoop 用于处理注册在它上面的 Channel 的所有的IO事件,一个 EventLoop 实例通常可以处理多个 Channel,
* 但是这取决于内部的实现细节
*/
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup {
/**
* 返回所属的EventExecutorGroup
*/
@Override
EventLoopGroup parent();
}
2.2 SingleThreadEventLoop
- SingleThreadEventLoop 实现了 EventLoop 接口,他会用一个单线程来执行提交的全部任务,功能上主是实现了注册 Channel 到 EventLoop 上的逻辑,他是 NioEventLoop 的抽象父类
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
//1.注册Channel到EventLoop上
promise.channel().unsafe().register(this, promise);
//2.返回ChannelPromise对象
return promise;
}
2.3 NioEventLoop
- NioEventLoop 对注册到其中的 Channel 的就绪事件以及对用户提交的任务进行处理,其中的处理过程会和 NIO 中的死循环select,然后处理得到的兴趣事件很类似,这些都留到后面分析
三、小结
-
本文主要是梳理 EventLoop 的继承体系,感觉比较机械,有些接口和类源码不多,有些接口和类源码比较多就没有完全给出来,但是感觉这些代码都是静态的,其实并不好帮助我们串联起来理解;
-
后面的文章,尝试这根据几个功能线来串联这些代码的流程,比如:NioEventLoop的实例化过程、Channel注册到NioEventLoop的过程、NioEventLoop执行定时任务、NioEventLoop如何像之前NIO那样处理多个Channel 并且得到 SelectyKeys 并处理事件等,通过这样的功能主线来将整个继承体系的代码关联起来,再对比NIO ,就会更好理解了。
-
其实EventLoop 本身就是一个线程池(这点从继承关系很好理解,但是它内部是一个单线程),由此它具备线程池相关的提交任务的功能,并且他会在一个死循环中处理注册在它上面的Channel的事件,和NIO中的Selector 一致的功能,这里可以参考 03-BIO、NIO到Netty 中NIO的代码
-
这些特性和细节在后面一一展开