3、NioEventLoopGroup的构建

在前一小节中我们大致浏览了NioEventLoopGroup的类图和与直接相关的类的类图,现在我们直接进入细节代码,分析NioEventLoopGroup的构建

下面这段代码,在第一小节我们已经看过了,这里再回顾下

scss 复制代码
public NioEventLoopGroup() {
        this(0);
}
            |
            V
public NioEventLoopGroup(int nThreads) {
        this(nThreads, (Executor) null);
}
            |
            V
public NioEventLoopGroup(int nThreads, Executor executor) {
        //SelectorProvider适用于打开selector多用复用器的提供者
        this(nThreads, executor, SelectorProvider.provider());
}
            |
            V
public NioEventLoopGroup(
            int nThreads, Executor executor, final SelectorProvider selectorProvider) {
        super(nThreads, executor, selectorProvider);
}
            |
            V
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
        //假如此时你的电脑是4核心的,按照MultithreadEventLoopGroup静态块的操作,这里的值就是8,也就是构建8个线程
        super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
            |
            V
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
        if (nThreads <= 0) {
            throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
        }

        if (executor == null) {
            //从上面一路走来,executor是null值,这里创建了一个ThreadPerTaskExecutor,从第一小节中可以知道它对于每个提交的任务都会使用
            //DefaultThreadFactory创建一个新的线程去执行
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }
        //构建子事件执行器数组
        //注意children是MultithreadEventExecutorGroup的成员变量
        children = new EventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
                //调用NioEventLoopGroup实现的newChild方法,上面我们已经看到过,它构建的EventExecutor是NioEventLoop
                children[i] = newChild(executor, args);
                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) {
                            //发生中断
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                }
            }
        }
        //这里又涉及到了一个类,从字面上来看就是Future监听器
        final FutureListener<Object> terminationListener = new FutureListener<Object>() {
            @Override
            public void operationComplete(Future<Object> future) throws Exception {
                //terminatedChildren已经解答了上面的问题,它就是用来记录停止执行器的个数
                //如果终止的执行器数量已经等于children的数量了,那么说明全都终止了,然后设置terminationFuture为null
                //这个啥意思呢?带着问题继续吧
                if (terminatedChildren.incrementAndGet() == children.length) {
                    terminationFuture.setSuccess(null);
                }
            }
        };

        for (EventExecutor e: children) {
            //给每个EventExecutor添加终止监听器,也就是每个执行器内部的任务完成都会调用这个监听方法
            e.terminationFuture().addListener(terminationListener);
        }

        Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
        Collections.addAll(childrenSet, children);
        //添加到只读集合中
        readonlyChildren = Collections.unmodifiableSet(childrenSet);
}

对以上代码进行分阶段分析,然后再总结下它做了什么,现在关联了什么,再画个序列图,这样我们才能清楚刚才都做了什么,才不至于忘记

NioEventLoopGroup的构建序列图

构建EventExecutor数组

前面说到构建EventExecutor数组的元素是NioEventLoop,我们来看看它是怎么构建的

scss 复制代码
//parent:这个值是上面的NioEventLoopGroup对象,executor:这个是ThreadPerTaskExecutor对象,selectorProvider:selector多路复用器提供者
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider) {
        super(parent, executor, false);
        if (selectorProvider == null) {
            throw new NullPointerException("selectorProvider");
        }
        provider = selectorProvider;
        selector = openSelector();
}
                    |
                    V
protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp) {
        super(parent, executor, addTaskWakesUp);
}
                    |
                    V
protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor, boolean addTaskWakesUp) {
        super(parent);

        if (executor == null) {
            throw new NullPointerException("executor");
        }

        //默认传入的是false
        this.addTaskWakesUp = addTaskWakesUp;
        this.executor = executor;
        //new LinkedBlockingQueue<Runnable>()
        //构建了一个无边界阻塞队列
        taskQueue = newTaskQueue();
}
                    |
                    V
protected AbstractEventExecutor(EventExecutorGroup parent) {
        this.parent = parent;
}

下面是它的序列图

下面是NioEventLoopGroup关系类图,省略了部分继承结构,继承结构可查看上一小节

好了,这样NioEventLoopGroup就构建好了。

相关推荐
y25087 分钟前
《Object类》
java·开发语言
曙曙学编程8 分钟前
初级数据结构——树
android·java·数据结构
BestandW1shEs14 分钟前
彻底理解消息队列的作用及如何选择
java·kafka·rabbitmq·rocketmq
爱吃烤鸡翅的酸菜鱼16 分钟前
Java算法OJ(8)随机选择算法
java·数据结构·算法·排序算法
码蜂窝编程官方19 分钟前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
Viktor_Ye36 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm38 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
一二小选手42 分钟前
【Maven】IDEA创建Maven项目 Maven配置
java·maven
J老熊1 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
猿java1 小时前
什么是 Hystrix?它的工作原理是什么?
java·微服务·面试