• Netty源码分析第2章(NioEventLoop)---->第3节: 初始化线程选择器


     

    Netty源码分析第二章:NioEventLoop

     

    第三节:初始化线程选择器

    到上一小节的MultithreadEventExecutorGroup类的构造方法:

    protected MultithreadEventExecutorGroup(int nThreads, Executor executor, 
                                            EventExecutorChooserFactory chooserFactory, Object... args) {
        //代码省略
        if (executor == null) {
            //创建一个新的线程执行器(1)
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }
        //构造NioEventLoop(2)
        children = new EventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
                children[i] = newChild(executor, args);
                success = true;
            } catch (Exception e) {
                throw new IllegalStateException("failed to create a child event loop", e);
            } finally {
               //代码省略
            }
        }
        //创建线程选择器(3)
        chooser = chooserFactory.newChooser(children);
        //代码省略
    }

    我们看第三步, 创建线程选择器:

    chooser = chooserFactory.newChooser(children);

    NioEventLoop都绑定一个chooser对象, 作为线程选择器, 通过这个线程选择器, 为每一个channel分配不同的线程

    我们看到newChooser(children)传入了NioEventLoop数组

    我们跟到DefaultEventExecutorChooserFactory类中的newChooser方法:

    public EventExecutorChooser newChooser(EventExecutor[] executors) { 
        if (isPowerOfTwo(executors.length)) { 
            return new PowerOfTowEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }

    这里通过 isPowerOfTwo(executors.length) 判断NioEventLoop的线程数是不是2的倍数, 然后根据判断结果返回两种选择器对象, 这里使用到java设计模式的策略模式

    根据这两个类的名字不难看出, 如果是2的倍数, 使用的是一种高性能的方式选择线程, 如果不是2的倍数, 则使用一种比较普通的线程选择方式

    我们简单跟进这两种策略的选择器对象中看一下, 首先看一下PowerOfTowEventExecutorChooser这个类:

    private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;
        PowerOfTowEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }
        @Override
        public EventExecutor next() {
            return executors[idx.getAndIncrement() & executors.length - 1];
        }
    }

    这个类实现了线程选择器的接口EventExecutorChooser, 构造方法中初始化了NioEventLoop线程数组

    重点关注下next()方法, next()方法就是选择下一个线程的方法, 如果线程数是2的倍数, 这里通过按位与进行计算, 所以效率极高

    再看一下GenericEventExecutorChooser这个类:

    private static final class GenericEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;
        GenericEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }
        @Override
        public EventExecutor next() {
            return executors[Math.abs(idx.getAndIncrement() % executors.length)];
        }
    }

    这个类同样实现了线程选择器的接口EventExecutorChooser, 并在造方法中初始化了NioEventLoop线程数组

    再看这个类的next()方法, 如果线程数不是2的倍数, 则用绝对值和取模的这种效率一般的方式进行线程选择

     

    这样, 我们就初始化了线程选择器对象

     

    上一节: NioEventLoopGroup之NioEventLoop的创建

    下一节: NioEventLoop线程启动

     

  • 相关阅读:
    C# GDI生成清晰【高质量】图片
    Myeclipse项目内容没有报错但是项目上面却有红色叉叉
    JRE System Library 与Java EE Libraries的区别
    [原创]Java导出Excel
    [原创]java获取word文档的条目化内容
    [原创]java获取word里面的文本
    各种java生成word解决方案的优缺点对比
    [原创]Java生成Word文档
    [原创]java实现word转pdf
    [原创]java调用PageOffice生成word
  • 原文地址:https://www.cnblogs.com/xiangnan6122/p/10202920.html
Copyright © 2020-2023  润新知