Netty源码解析 -- 事件循环机制实现原理

本文深入探讨Netty的事件循环机制,重点解析EventLoop、EventExecutorGroup、NioEventLoop等核心类的工作原理,以及如何处理IO事件和异步任务。通过对Netty 4.1源码的分析,揭示了事件循环在NIO事件处理中的关键角色。
摘要由CSDN通过智能技术生成

本文主要分享Netty中事件循环机制的实现。
源码分析基于Netty 4.1

EventLoop

前面分享服务端和客户端启动过程的文章中说过,Netty通过事件循环机制(EventLoop)处理IO事件和异步任务,简单来说,就是通过一个死循环,不断处理当前已发生的IO事件和待处理的异步任务。示例如下

while(true) {
    process(selector.select());

    process(getTask());
}

这种事件循环机制也是一种常用的IO事件处理机制,包括Redis,Mysql都使用了类似的机制。

关于异步任务,前面文章说过,EventLoop实现了(jvm)Executor的接口,execute方法可以提供异步任务。
register,bind,connect等操作,都会提交一个任务给EventLoop处理。如

if (eventLoop.inEventLoop()) {
    register0(promise); 
} else {
    eventLoop.execute(new Runnable() {  
        public void run() {
            register0(promise);
        }
    });
}

下面看一下Netty中事件循环机制相关的类。

EventExecutor,事件执行器,负责处理事件。
EventExecutorGroup维护了一个EventExecutor链表,它继承了ScheduledExecutorService,execute方法通过next方法选择一个EventExecutor,并调用EventLoop#execute处理事件。
(EventExecutor继承了EventExecutorGroup,可以看做一个特殊的EventExecutorGroup,其execute方法可以提交一个任务任务)

EventLoop,事件循环器,继承了EventExecutor,通过循环不断处理注册于其上的Channel的IO事件。
EventLoopGroup接口则继承了EventExecutorGroup,负责调度EventLoop。

SingleThreadEventExecutor实现了EventExecutor,它会创建一个新线程,并在该线程上处理事件,可以理解为单线程处理器。
MultithreadEventExecutorGroup实现EventExecutorGroup,可以理解为多线程处理器(实际上是维护了多个EventExecutor,一个EventExecutor可以理解为一个线程),newChild方法构造具体的EventExecutor。
MultithreadEventExecutorGroup可以配置EventExecutor数量,即线程数量。
EventExecutorChooserFactory.EventExecutorChooser负责选择一个EventExecutor执行实际操作。

NioEventLoop继承了SingleThreadEventExecutor,负责处理NIO事件。所以,一个NioEventLoop对象可以看做是一个线程。
NioEventLoop也实现了EventLoop接口,它实现了事件循环机制,是Netty核心类。

MultithreadEventLoopGroup继承了MultithreadEventExecutorGroup,并实现了EventLoopGroup,其newChild方法构造具体的EventLoop。
NioEventLoopGroup#newChild会构建NioEventLoop。

EventLoop各实现类关系如下

 

启动

SingleThreadEventExecutor关键字段

private final Queue<Runnable> taskQueue;    // 待处理异步任务
private volatile Thread thread;                // EventLoop执行线程,即SingleThreadEventExecutor创建的新线程
private final Executor executor;            // java.util.concurrent.Executor,负责创建线程

当我们通过execute方法提交任务时,如果还没有创建执行新线程,会通过SingleThreadEventExecutor#executor一个新线程,并在新线程中调用run方法(run方法由子类实现,负责实现事件循环机制,新线程是EventLoop真正执行线程)。

SingleThreadEventExecutor#execute

public void execute(Runnable task) {
    ...

    boolean inEventLoop = inEventLoop();
    // #1
    addTask(task);
    // #2
    if (!inEventLoop) {
        startThread();
        // #3
        if (isShutdown()) {
            ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值