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的指数倍, 返回PowerOfTwoEventExecutorChooserreturn 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;}@Overridepublic 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,保证了最大值是 数组的长度减一, 如此往复

转载于:https://www.cnblogs.com/ZhuChangwu/p/11237899.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

attachEvent和addEventListener

attachEvent和addEventListener在前端开发过程中经常性的使用,他们都可以用来绑定脚本事件,取代在html中写 obj.οnclickmethod。相同点: 它们都是DOM对象的方法,可以实现一种事件绑定多个事件处理函数。 obj document.getElemen…

java多线程总结一:线程的两种创建方式及优劣比较

1、通过实现Runnable接口线程创建 (1).定义一个类实现Runnable接口,重写接口中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。 (2).创建Runnable接口实现类的对象。 (3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象。&…

如果删除github上项目的文件

1. 你要有前面一章的开发平台和github插件,下面就是基于前面来做的。 如何删掉你github上的文件呢?想必你的电脑有一个下载的git工具了,如果还是没有的话,请用npm下载一个git。这是我已经下载好的。 2. 然后打开这个git&#xff…

在WildFly和OpenShift上的WebSocket聊天

聊天是解释WebSocket的最典型示例之一。 它是一个相当常用的界面,可以很容易地解释WebSocket的基本概念。 当然,Java EE 7 WebSocket也有一个, 在这里可用 ! 您可以使用以下步骤在WildFly上轻松运行它: curl -O http:…

recv, recvfrom, recvmsg

recv,recvfrom,recvmsg函数用于从套接字接收信息。 ssize_t recv (int s, void *buf, size_t len, int flags);ssize_t recvfrom (int s, void * restrict buf, size_t len, int flags, struct sockaddr * restrict from, socklen_t * restrict fromlen);ssize_t recvmsg (int…

[解决]电信彩信网关开发错误-SOAP_VERSIONMISMATCH

上一个文章&#xff1a;[求救]电信彩信网关开发错误&#xff0d;SOAP_VERSIONMISMATCH 说的问题<messageId>SVC0001</messageId> <text>SOAP_VERSIONMISMATCH</text> 已经解决&#xff0c;主要是查看了网上的一个同学的帖子&#xff0c;非常感谢。再来…

Ubuntu20.04纯命令配置PCL(点云库)

Ubuntu20.04纯命令配置PCL&#xff08;点云库&#xff09; 最近在学习点云库&#xff08;PCL&#xff09;的使用&#xff0c;第一步就是在自己的电脑安装配置PCL。 首先&#xff0c;对于ubuntu 16.04以上版本&#xff0c;可以直接使用命令进行安装&#xff0c;新建好一个文件夹…

css html应用实例1:滑动门技术的简单实现

关于滑动门&#xff0c;现在的页面中好多地方都会用到滑动门&#xff0c;一般用作于导航背景&#xff0c;它的官方解释如下&#xff1a; 滑动门&#xff1a;根据文本自适应大小&#xff0c;根据背景的层叠性制作&#xff0c;并允许他们在彼此之上进行滑动&#xff0c;以创造出…

魔戒1

转载于:https://www.cnblogs.com/moonlightpeng/p/11240880.html

得到python默认的帮助文档

python的help文档很好&#xff0c;就是有时候help一下给出好几页来&#xff0c;甚至有些帮助根本就看不到了(我想应该有其他方法可以解决&#xff0c;只是我不想去查了)&#xff0c;因为这个可以通过一个很简单的python脚本搞定。这里举例为证&#xff0c;比如我想得到Tkinter的…

如何在Java中将图像上传到DropBox

本教程介绍了如何将图像上传到放置框并获取上传图像的公共URL。 首先&#xff0c;我们必须使用应用程序控制台创建一个DropBox API应用程序 。 创建应用程序后&#xff0c;您可以在应用程序属性中获取应用程序密钥和秘密密钥。 现在在您的pom文件中添加以下依赖项。 <dep…

css3动画整理

css3动画主要常用的属性有 变形&#xff08;transform&#xff09;&#xff0c;转换&#xff08;transition&#xff09;&#xff0c;动画&#xff08;animation&#xff09;三种。 变形&#xff08;transform&#xff09;主要有以下几种方式&#xff1a; 旋转rotate&#xff1…

jQuery应用实例2:简单动画

效果&#xff1a; 代码&#xff1a; 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2 <html xmlns"http://www.w3.org/1999/xhtml">3 <head>…

程序员成熟的标志

程序员在经历了若干年编程工作之后&#xff0c;很想知道自己水平到底如何&#xff1f;自己是否已经成为成熟的程序员&#xff1f;虽然程序员会对自己有一个自我评价&#xff0c;但是&#xff0c;自己的评价和社会的评价、专业的评价会有差异&#xff0c;所以程序员自己并不能肯…

Spring Data JPA教程:简介

创建使用Java Persistence API的存储库是一个繁琐的过程&#xff0c;需要大量时间&#xff0c;并且需要大量样板代码。 通过执行以下步骤&#xff0c;我们可以消除一些样板代码&#xff1a; 创建一个抽象的基础存储库类&#xff0c;该类为实体提供CRUD操作。 创建扩展抽象基础…

深入了解React组件重新渲染的条件和生命周期

React组件rerender的真正条件 当前组件的State中的属性改变时且当前组件的shouldcomponentupdate返回true&#xff0c;那么当前组件会rerender组件的props中的任一属性的值有变化(即使这个任一属性的值是对象&#xff0c;变化的仅仅是该对象中的某属性的值&#xff0c;此刻也算…

对怀孕的人有害的食物。。。朋友们记住咯!(欢迎转载)

有几个同事和朋友要生BB啦&#xff0c;好东东&#xff0c;转给你们提前学习一下~ 容易流产食物&#xff1a; 1、螃蟹&#xff1a;它味道鲜美&#xff0c;但其性寒凉&#xff0c;有活血祛瘀之功&#xff0c;故对孕妇不利&#xff0c;尤其是蟹爪&#xff0c;有明显的堕胎作用。 2…

Vss服务端用户存在,但客户端登陆不进去

打开客户端Vss提示“Cannot find SS.INI file for user userName”,这个错误是找不到用户userName的SS.INI文件。 解决办法 在服务器上找到Vss共享的文件夹&#xff0c;打开此文件夹下的users文件夹&#xff0c;然后找到userName文件夹打开后&#xff1a; 如果没有SS.INI文件&a…

Hystrix中的批量(折叠)请求

Hystrix具有折叠&#xff08;或批处理&#xff09;请求的高级功能。 如果两个或多个命令同时运行相似的请求&#xff0c;Hystrix可以将它们组合在一起&#xff0c;运行一个批处理请求&#xff0c;并将拆分结果分派回所有命令。 首先让我们看看Hystrix如何工作而不会崩溃。 假设…

C#繁简转换

//1.using System.Runtime.InteropServices; //2.import kernel32.dll [DllImport("kernel32.dll",EntryPoint "LCMapStringA")]    public static extern int LCMapString(int Locale,int dwMapFlags,byte[] lpSrcStr,int cchSrc,byte[] lpDestStr,…