Netty中的策略者模式

简介: Netty中的策略者模式

策略者模式的特点#


在设计类的继承体系时,我们会刻意的把公共的部分都提取到基类中

比如先设计Person类,把人类都具有的行为放到这个Person,特有的行为设计成抽象方法,让子类具体去实现, 这样后续无论我们再去构造学生,还是构造老师,大家都继承Person,就达到了代码复用的目的

但是这样问题就来了,对老师类来说,需要有教学的行为,假如这个方法以抽象方法的形式放在基类,那么对于继承了Person的学生类来说就不对了,因为没有要求学生一定会教学,但是现在学生就得实现这个方法

如果我们把老师的教学的行为作为 老师类的私有, 这时候,小明教小李学习, 就意味着对小明来说,他需要教学的行为, 前前后后看起来就开始矛盾了, 到底怎么处理呢?

策略者模式,就解决了这个问题, 它把行为抽象成了接口,以接口+实现的方式,解决上面的问题, 就上面的例子来说,可以把教学设计成接口,任何类,只要实现了这个接口,就可以教学,而不一定强制要求只有老师才可以实现它

总的来说,策略模式,就是将行为抽象成接口+实现的模式


Netty中策略者模式的使用#


netty的bossgroup中接收到了新的连接之后会使用选择器Chooser,从WorkerGroup中选择出一个EventLoop, 然后把这个连接注册进选出的 EventLoop

netty的选择器,使用的就是策略者模式,将选择的行为 设计成接口,不同的选择器根据自己不同的需求用不用的方式实现选择器接口

行为接口


@UnstableApi
public interface EventExecutorChooserFactory {
EventExecutorChooser newChooser(EventExecutor[] executors);
@UnstableApi
interface EventExecutorChooser {
    EventExecutor next();
}
}


选择器不同的实现:


if (isPowerOfTwo(executors.length)) {// todo 如果是2的指数倍, 返回PowerOfTwoEventExecutorChooser
    return new PowerOfTwoEventExecutorChooser(executors);
} else {// todo  否则返回同样的实例
    return new GenericEventExecutorChooser(executors);
}


根据线程执行器的数量确定使用那种具体的行为


行为1:PowerOfTwoEventExecutorChooser#


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


主要看它的executors[idx.getAndIncrement() & executors.length - 1]

进行速度更快的与运算


1 & 1 = 1
1 & 0 = 0
0 & 1 = 0


当数组的长度是2的幂次方时, 用二进制表示就是1111... 全是1, 再减去1 ,就是0111...

无论前面的数是谁,对一个 0111... 进行与运算,得到的结果就是从0-0111...大小的数, 循环往复


行为2:GenericEventExecutorChooser#


private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
GenericEventExecutorChooser(EventExecutor[] executors) {
    this.executors = executors;
}
@Override
public EventExecutor next() {
    // todo 从0开始到最后一个, 再从零开始,到最后一个
    return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}


主要的一步就是Math.abs(idx.getAndIncrement() % executors.length)

可以看到,从0开始一直往后对数组的长度取余数,小数对大数取余数=小数, 保证了数组的下标从0开始递增, 自己对自己取余数=0,保证了最大值是 数组的长度减一, 如此往复

相关文章
|
监控 NoSQL Java
Netty高性能架构之Reactor模式
在讨论Netty的架构模式之前,我们先来介绍下Reactor模式,因为Netty的架构模式是在此基础上演变而来的
Netty高性能架构之Reactor模式
灵魂一击!Netty系列笔记之Reactor模式(建议收藏)
一、什么是 Reactor 三种 IO 模式和对应的开发模式如下: BIONIOAIOThread-Per-ConnectionReactorProactor Reactor 是一种开发模式,核心流程为: 1、注册感兴趣的事件 2、扫描是否有感兴趣的事件发生 3、事件发生后做相应的处理
|
Java
Netty「基石」之Reactor模式
Netty「基石」之Reactor模式
192 0
|
设计模式 Java 程序员
Netty线程模型 - Reactor 模式
我相信有很多人会对这个Reactor模式比较陌生,但是Netty这个名字大家都会比较熟悉,即使没有学习使用过,也会对它有所耳闻,它可以说是Java高性能网络编程的代名词。Reactor模式就是Netty线程模型设计的核心,本文我们就以Reactor模式入手,探究一下经典的设计。
179 0
|
Java 调度
【Netty】反应器 Reactor 模式 ( 单反应器 Reactor 单线程 | 单反应器 Reactor 多线程 )
【Netty】反应器 Reactor 模式 ( 单反应器 Reactor 单线程 | 单反应器 Reactor 多线程 )
183 0
【Netty】反应器 Reactor 模式 ( 单反应器 Reactor 单线程 | 单反应器 Reactor 多线程 )
|
缓存 网络协议 安全
【Netty】Netty 简介 ( 原生 NIO 弊端 | Netty 框架 | Netty 版本 | 线程模型 | 线程 阻塞 IO 模型 | Reactor 模式引入 )
【Netty】Netty 简介 ( 原生 NIO 弊端 | Netty 框架 | Netty 版本 | 线程模型 | 线程 阻塞 IO 模型 | Reactor 模式引入 )
227 0
【Netty】Netty 简介 ( 原生 NIO 弊端 | Netty 框架 | Netty 版本 | 线程模型 | 线程 阻塞 IO 模型 | Reactor 模式引入 )
|
Java
Netty的Reactor模式(上)
Netty的Reactor模式
146 0
Netty的Reactor模式(上)
|
Java Linux Windows
Netty支持的三种I/O模式
Netty支持的三种I/O模式
181 0
Netty支持的三种I/O模式