netty学习1:NioEventLoopGroup 事件循环组源码分析

在创建bossGroup和workGroup的时候,会用到NioEventLoopGroup对象,顾名思义,是NioEventLoop的集合,如何循环,如何使用。分析源码 如下

1、查看NioEventLoopGroup的继承关系图:

实现了两个接口,Exector和Iterable ,其中AbstractEventExecutorGroup重写了execute方法,循环执行NioEventLoop的run方法。

@Override
public void execute(Runnable command) {
   //循环执行NioEventLoopGroup中的NioEventLoop的execute方法 ,最终会调用到io.netty.util.concurrent.SingleThreadEventExecutor#execute(java.lang.Runnable, boolean)方法,也就是循环组的Loop意义所在
    next().execute(command);
}

2.构造函数

io.netty.util.concurrent.MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, java.util.concurrent.Executor, io.netty.util.concurrent.EventExecutorChooserFactory, java.lang.Object...) 查看构造函数,实现如下功能

1. 创建每线程任务执行器

2.创建事件循环组的组员 :children数组,实例化每一个children对象

3.创建EventExecutorChooser选择器 可循环调用children数组中的对象

4.给children对象挨个添加监听事件,回调使用

5.给readonlyChildren赋值,通过迭代器遍历children数组

protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
                                        EventExecutorChooserFactory chooserFactory, Object... args) {
    ...
    if (executor == null) {
        //创建每一个线程任务执行器
        executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
    }
    //创建child的数组  下面会挨个赋值
    children = new EventExecutor[nThreads];

    for (int i = 0; i < nThreads; i ++) {
        boolean success = false;
        try {
            children[i] = newChild(executor, args);//创建EventLoop  参数executor
            success = true;
        } catch (Exception e) {
            // TODO: Think about if this is a good exception type
            throw new IllegalStateException("failed to create a child event loop", e);
        } finally {
            if (!success) {//如果创建失败 挨个优雅关闭
                for (int j = 0; j < i; j ++) {
                    children[j].shutdownGracefully();
                }

                for (int j = 0; j < i; j ++) {
                    EventExecutor e = children[j];
                    try {
                        while (!e.isTerminated()) {
                            e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
                        }
                    } catch (InterruptedException interrupted) {
                        // Let the caller handle the interruption.
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }
    }
    //创建选择器  如果size是2的倍数 就与运算取模  否则除数取模  next作用就是获取下一个EventLoop
    //线程组 会通过chooser找到对应的下一个处理线程
    chooser = chooserFactory.newChooser(children);

    final FutureListener<Object> terminationListener = new FutureListener<Object>() {
        @Override
        public void operationComplete(Future<Object> future) throws Exception {//回调方法operationComplete
            if (terminatedChildren.incrementAndGet() == children.length) {
                terminationFuture.setSuccess(null);
            }
        }
    };

    for (EventExecutor e: children) {//每一个EventLoop都添加监听事件
        e.terminationFuture().addListener(terminationListener);
    }

    Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
    Collections.addAll(childrenSet, children);
    readonlyChildren = Collections.unmodifiableSet(childrenSet);
}

3.io.netty.util.concurrent.MultithreadEventExecutorGroup#newChild方法  创建group的组员信息

实现方法在io.netty.channel.nio.NioEventLoopGroup#newChild

protected EventLoop newChild(Executor executor, Object... args) throws Exception {
    SelectorProvider selectorProvider = (SelectorProvider) args[0];
    SelectStrategyFactory selectStrategyFactory = (SelectStrategyFactory) args[1];
    RejectedExecutionHandler rejectedExecutionHandler = (RejectedExecutionHandler) args[2];
    EventLoopTaskQueueFactory taskQueueFactory = null;
    EventLoopTaskQueueFactory tailTaskQueueFactory = null;

    int argsLength = args.length;
    if (argsLength > 3) {
        taskQueueFactory = (EventLoopTaskQueueFactory) args[3];
    }
    if (argsLength > 4) {
        tailTaskQueueFactory = (EventLoopTaskQueueFactory) args[4];
    }
    //创建NioEventLoop 
    return new NioEventLoop(this, executor, selectorProvider,
            selectStrategyFactory.newSelectStrategy(),
            rejectedExecutionHandler, taskQueueFactory, tailTaskQueueFactory);
}

返回的是NioEventLoop对象  查看NioEventLoop的继承关系图 它也实现了Executor接口,在io.netty.util.concurrent.SingleThreadEventExecutor#execute(java.lang.Runnable, boolean)中重写了该方法

 4.ioEventLoop的构造函数

NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
             SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
             EventLoopTaskQueueFactory taskQueueFactory, EventLoopTaskQueueFactory tailTaskQueueFactory) {
    //继续调用父类的构造方法  最终调用到SingleThreadEventExecutor
    super(parent, executor, false, newTaskQueue(taskQueueFactory), newTaskQueue(tailTaskQueueFactory),
            rejectedExecutionHandler);
    this.provider = ObjectUtil.checkNotNull(selectorProvider, "selectorProvider");
    this.selectStrategy = ObjectUtil.checkNotNull(strategy, "selectStrategy");
    final SelectorTuple selectorTuple = openSelector();//获取Selector选择器
    this.selector = selectorTuple.selector;
    this.unwrappedSelector = selectorTuple.unwrappedSelector;
}

查看父类的构造方法io.netty.util.concurrent.SingleThreadEventExecutor#SingleThreadEventExecutor(io.netty.util.concurrent.EventExecutorGroup, java.util.concurrent.Executor, boolean, java.util.Queue<java.lang.Runnable>, io.netty.util.concurrent.RejectedExecutionHandler)

protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
                                    boolean addTaskWakesUp, Queue<Runnable> taskQueue,
                                    RejectedExecutionHandler rejectedHandler) {
    super(parent);
    this.addTaskWakesUp = addTaskWakesUp;
    this.maxPendingTasks = DEFAULT_MAX_PENDING_EXECUTOR_TASKS;
    //通过MultithreadEventExecutorGroup的构造函数中创建出来的executor对象创建了新的executor
    //this是 NioEventLoop 对象
    this.executor = ThreadExecutorMap.apply(executor, this);
    //保存了任务队列
    this.taskQueue = ObjectUtil.checkNotNull(taskQueue, "taskQueue");
    //拒绝策略
    this.rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");
}

 io.netty.channel.nio.NioEventLoop#openSelector 开启选择器  也就是用SelectorTuple对象包装了原生nio的selector对象

查看io.netty.util.concurrent.DefaultEventExecutorChooserFactory#newChooser 选择器方法

数组是2的倍数就与运算取模  否则就余运算取模 

public EventExecutorChooser newChooser(EventExecutor[] executors) {
    if (isPowerOfTwo(executors.length)) {//如果是2的倍数
        return new PowerOfTwoEventExecutorChooser(executors);//与运算获取next
    } else {
        return new GenericEventExecutorChooser(executors);//取余数取模
    }
}

我们debug调试代码发现 无论bossGroup还是workerGroup  结构都如下:

 1.children就是组员信息  每一个对象都是NioEventLoop对象

 2. defaultPromise对象 nio都是异步操作 需要future对象阻塞获取异步返回结果,在全局变量中直接赋值创建 后续分析

 3. chooser选择器  挨个循环获取children的对象信息

children中的每一个NioEventLoop中包含了

1.selector 多路复用器

2.taskQueue 任务队列

3.executor执行器 

后续再NioEventLoop的run方法中都会被用到

简单总结:

1.NioEventLoopGroup即创建线程组 bossGroup就是创建一个boss的线程  workGroup会创建指定个数|默认个数的线程

2.每一个线程对象是通过chooser对象来关联的  可以通过chooser对象指定异步任务交给组中下一个线程去处理

3.每一个NioEventLoop都包含了一个selector多路复用器 bossGroup用来监听OP_ACCEPT事件,当事件发生之后,获取到NioSocketChannel对象交给workGroup的线程异步去处理

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值