当前位置: 首页 > news >正文

Netty中用到了哪些设计模式

Netty作为一个高性能的网络通信框架,里面有很多优秀的代码值得我们学习,今天我们一起看下Netty中用到了哪些设计模式。

一、单例模式

Netty通过 NioEventLoop 将通道注册到选择器,并在事件循环中多路复用它们。其中提供了一个选择策略对象 SelectStrategy,它只有一个默认实现:DefaultSelectStrategy。

/*** Default select strategy.*/
final class DefaultSelectStrategy implements SelectStrategy {static final SelectStrategy INSTANCE = new DefaultSelectStrategy();private DefaultSelectStrategy() { }@Overridepublic int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) throws Exception {return hasTasks ? selectSupplier.get() : SelectStrategy.SELECT;}
}

还有 ReadTimeoutException 和 WriteTimeoutException

/*** A {@link TimeoutException} raised by {@link ReadTimeoutHandler} when no data* was read within a certain period of time.*/
public final class ReadTimeoutException extends TimeoutException {private static final long serialVersionUID = 169287984113283421L;public static final ReadTimeoutException INSTANCE = PlatformDependent.javaVersion() >= 7 ?new ReadTimeoutException(true) : new ReadTimeoutException();ReadTimeoutException() { }private ReadTimeoutException(boolean shared) {super(shared);}
}
/*** A {@link TimeoutException} raised by {@link WriteTimeoutHandler} when a write operation* cannot finish in a certain period of time.*/
public final class WriteTimeoutException extends TimeoutException {private static final long serialVersionUID = -144786655770296065L;public static final WriteTimeoutException INSTANCE = PlatformDependent.javaVersion() >= 7 ?new WriteTimeoutException(true) : new WriteTimeoutException();private WriteTimeoutException() { }private WriteTimeoutException(boolean shared) {super(shared);}
}

二、工厂模式

工厂模式是非常常见的一种模式,Netty中也使用到,比如 上面提到的选择策略工厂: DefaultSelectStrategyFactory

/*** Factory which uses the default select strategy.*/
public final class DefaultSelectStrategyFactory implements SelectStrategyFactory {public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory();private DefaultSelectStrategyFactory() { }@Overridepublic SelectStrategy newSelectStrategy() {return DefaultSelectStrategy.INSTANCE;}
}

三、策略模式

在默认的事件执行选择工厂 DefaultEventExecutorChooserFactory 的 newChooser 方法中,根据数组参数的长度是否是2的幂 来选择不同的 EventExecutorChooser。两种方式都是简单的轮询方式,只是方式不同。

    @Overridepublic EventExecutorChooser newChooser(EventExecutor[] executors) {if (isPowerOfTwo(executors.length)) {return new PowerOfTwoEventExecutorChooser(executors);} else {return new GenericEventExecutorChooser(executors);}}

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];}}private static final class GenericEventExecutorChooser implements EventExecutorChooser {// Use a 'long' counter to avoid non-round-robin behaviour at the 32-bit overflow boundary.// The 64-bit long solves this by placing the overflow so far into the future, that no system// will encounter this in practice.private final AtomicLong idx = new AtomicLong();private final EventExecutor[] executors;GenericEventExecutorChooser(EventExecutor[] executors) {this.executors = executors;}@Overridepublic EventExecutor next() {return executors[(int) Math.abs(idx.getAndIncrement() % executors.length)];}}

四、装饰者模式

WrappedByteBuf 就是对 ByteBuf的装饰,来实现对它的增加。
class WrappedByteBuf extends ByteBuf {protected final ByteBuf buf;protected WrappedByteBuf(ByteBuf buf) {if (buf == null) {throw new NullPointerException("buf");}this.buf = buf;}......
}

五、责任链模式

ChannelPipeline 就是用到了责任链模式,所谓的责任链模式是指:它允许多个对象在处理请求时形成一条链,每个对象都有机会处理请求,将请求沿着链传递,直到有一个对象处理它为止。

/*** The default {@link ChannelPipeline} implementation.  It is usually created* by a {@link Channel} implementation when the {@link Channel} is created.*/
public class DefaultChannelPipeline implements ChannelPipeline {static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);private static final String HEAD_NAME = generateName0(HeadContext.class);private static final String TAIL_NAME = generateName0(TailContext.class);private static final FastThreadLocal<Map<Class<?>, String>> nameCaches =new FastThreadLocal<Map<Class<?>, String>>() {@Overrideprotected Map<Class<?>, String> initialValue() {return new WeakHashMap<Class<?>, String>();}};private static final AtomicReferenceFieldUpdater<DefaultChannelPipeline, MessageSizeEstimator.Handle> ESTIMATOR =AtomicReferenceFieldUpdater.newUpdater(DefaultChannelPipeline.class, MessageSizeEstimator.Handle.class, "estimatorHandle");final HeadContext head;final TailContext tail;private final Channel channel;private final ChannelFuture succeededFuture;private final VoidChannelPromise voidPromise;private final boolean touch = ResourceLeakDetector.isEnabled();private Map<EventExecutorGroup, EventExecutor> childExecutors;private volatile MessageSizeEstimator.Handle estimatorHandle;private boolean firstRegistration = true;/*** This is the head of a linked list that is processed by {@link #callHandlerAddedForAllHandlers()} and so process* all the pending {@link #callHandlerAdded0(AbstractChannelHandlerContext)}.** We only keep the head because it is expected that the list is used infrequently and its size is small.* Thus full iterations to do insertions is assumed to be a good compromised to saving memory and tail management* complexity.*/private PendingHandlerCallback pendingHandlerCallbackHead;/*** Set to {@code true} once the {@link AbstractChannel} is registered.Once set to {@code true} the value will never* change.*/private boolean registered;protected DefaultChannelPipeline(Channel channel) {this.channel = ObjectUtil.checkNotNull(channel, "channel");succeededFuture = new SucceededChannelFuture(channel, null);voidPromise =  new VoidChannelPromise(channel, true);tail = new TailContext(this);head = new HeadContext(this);head.next = tail;tail.prev = head;}

相关文章:

Netty中用到了哪些设计模式

Netty作为一个高性能的网络通信框架&#xff0c;里面有很多优秀的代码值得我们学习&#xff0c;今天我们一起看下Netty中用到了哪些设计模式。 一、单例模式 Netty通过 NioEventLoop 将通道注册到选择器&#xff0c;并在事件循环中多路复用它们。其中提供了一个选择策略对象 S…...

第67期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…...

Chrome 浏览器插件获取网页 window 对象(方案三)

前言 最近有个需求&#xff0c;是在浏览器插件中获取 window 对象下的某个数据&#xff0c;当时觉得很简单&#xff0c;和 document 一样&#xff0c;直接通过嵌入 content_scripts 直接获取&#xff0c;然后使用 sendMessage 发送数据到插件就行了&#xff0c;结果发现不是这…...

动态规划-分割回文串ⅡⅣ

在本篇博客中将介绍分割回文串Ⅱ以及分割回文串Ⅳ这两个题目。 分割回文串Ⅱ 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文串。 返回符合要求的 最少分割次数 。 示例&#xff1a; 输入&#xff1a;s "aabac" 输…...

Python编码系列—Python项目维护与迭代:持续进化的艺术

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…...

【鸿蒙开发工具报错】Build task failed. Open the Run window to view details.

Build task failed. Open the Run window to view details. 问题描述 在使用deveco-studio 开发工具进行HarmonyOS第一个应用构建开发时&#xff0c;通过Previewer预览页面时报错&#xff0c;报错信息为&#xff1a;Build task failed. Open the Run window to view details.…...

k8s集群部署:容器运行时

1. 卸载旧版本 Docker # 卸载旧版本的 Docker 组件 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine注释: 该命令会移除系统中现有的 Docker 及其相关组件&#xff0…...

PHP7 的内核结构

PHP7 是 PHP 语言的一个重要版本&#xff0c;带来了许多性能提升和语言特性改进。要深入了解 PHP7 的内核&#xff0c;我们需要探讨其设计和实现的关键方面&#xff0c;包括 PHP 的执行模型、内存管理、编译和优化过程等。 1. PHP7 的内核结构 1.1 执行模型 PHP 是一种解释型…...

JVM合集

序言: 1.什么是JVM? JVM就是将javac编译后的.class字节码文件翻译为操作系统能执行的机器指令翻译过程: 前端编译:生成.class文件就是前端编译后端编译:通过jvm解释(或即时编译或AOT)执行.class文件时跨平台的,jvm并不是跨平台的通过javap进行反编译2.java文件是怎么变…...

tomcat端口被占用解决方法

在安装目录的conf下修改server.xml文件&#xff0c;修改后保存重启即可...

全新的训练算法:Reflection 70B进入大众的视野

在2024年9月6日&#xff0c;大模型的圈子迎来了一位新成员——Reflection 70B&#xff0c;它横扫了MMLU、MATH、IFEval、GSM8K等知名的模型基准测试&#xff0c;完美超越了GPT-4o&#xff0c;同时也超越了Claude3.5 Sonnet成为了新的大模型之王&#xff0c;Reflection 70B到底是…...

静态标注rtk文件参数解析

目录 在静态标注中&#xff0c;rtk(Real-Time Kinematic)文件的主要作用 rtk文件包含几种类型数据 具体作用 具体示例 %RAWIMUSA #INSPVAXA $GPRMC 背景&#xff1a; 最近工作中涉及到静态标注 slam相关&#xff0c;因为初入门&#xff0c;对于rtk文件中有很多参数&…...

TensorFlow和PyTorch小知识

TensorFlow和PyTorch是当前最流行的两个开源机器学习库&#xff0c;它们都广泛用于研究和工业界的深度学习项目。下面是对它们的介绍&#xff1a; 1&#xff0c;TensorFlow - **开发背景&#xff1a;** TensorFlow最初由Google Brain Team开发&#xff0c;并于2015年11月开源…...

Java证书信息收集

1.Java二级 【NCRE 二级Java语言程序设计02】考试流程及二级Java大纲_java语言程序设计计算机二级-CSDN博客...

flink写入hudi MOR表

第一步&#xff1a;创建flink内存表从kafka读取数据&#xff1a; DROP TABLE IF EXISTS HUDI_KAFKA_DEBEZIUM_ZHANG; CREATE TABLE IF NOT EXISTS HUDI_KAFKA_DEBEZIUM_ZHANG( ID STRING comment 编码 ,NAME STRING comment 名称 ,PRIMARY KEY(RCLNT,RLDNR,RRCTY,RVERS,RYEAR,…...

智能工厂程序设计 之-2 (Substrate) :三个世界--“存在的意义”-“‘我’的价值的实现” 之2

Q13、我刚看了一下前门前面的讨论。有一段文字您的重新 理解一下。那就是&#xff1a; 对题目 的另一角度&#xff08; “智能工厂的程序设计”的三个层次词 分别关注的问题 及其 解决 思路的描述&#xff09;的解释&#xff1a; 三个不同层次&#xff08;深度&#xff09;&…...

概要设计例题

答案&#xff1a;A 知识点&#xff1a; 概要设计 设计软件系统的总体结构&#xff1a;采用某种方法&#xff0c;将一个复杂的系统按照功能划分成模块&#xff1b;确定每个模块的功能&#xff1b;确定模块之间的调用关系&#xff1b;确定模块之间的接口&#xff0c;即模块之间…...

注册表模式:使用注册表和装饰器函数的模块化设计

在现代软件开发中&#xff0c;模块化设计是提高代码可维护性和可扩展性的关键技术之一。本文将探讨如何使用注册表&#xff08;Registry&#xff09;和装饰器函数&#xff08;Decorator Function&#xff09;来实现模块化设计&#xff0c;提升代码的灵活性和可扩展性。 什么是…...

怎样将vue项目 部署在ngixn的子目录下

如果同一服务器的80端口下,需要部署两个或以上数量的vue项目,那么就需要将其中一个vue项目部署在根目录下,其他的项目部署在子目录下. 像这样的配置 访问根目录 / 访问灭火器后台管理,访问 /mall/ 访问商城的后台管理 那么商场的vue项目,这样配置,才能在/mall/下正常访问? 1…...

FPGA开发:Verilog数字设计基础

EDA技术 EDA指Electronic Design Automation&#xff0c;翻译为&#xff1a;电子设计自动化&#xff0c;最早发源于美国的影像技术&#xff0c;主要应用于集成电路设计、FPGA应用、IC设计制造、PCB设计上面。 而EDA技术就是指以计算机为工具&#xff0c;设计者在EDA软件平台上…...

关键指标自动提取(使用千问)

办公表格中通常包含海量数据&#xff0c;但核心决策仅需聚焦少数关键指标&#xff0c;如毛利率、达成率、增长率。千问可基于业务场景&#xff0c;自动识别并计算核心指标&#xff0c;避免数据冗余导致的决策低效。1.常用关键指标类型业务运营指标&#xff1a;销售额、成交量、…...

从仿真到综合:手把手拆解Verilog中always@(*)与assign的真实差异(附Testbench调试技巧)

从仿真到综合&#xff1a;手把手拆解Verilog中always(*)与assign的真实差异&#xff08;附Testbench调试技巧&#xff09; 在数字IC设计领域&#xff0c;Verilog作为硬件描述语言的代表&#xff0c;其语法细节往往直接影响设计质量。always(*)和assign作为描述组合逻辑的两种主…...

用Arduino搞定维特JY61P姿态传感器:从串口数据解析到欧拉角获取(附完整代码)

Arduino实战&#xff1a;JY61P姿态传感器数据解析与欧拉角计算全指南 刚拿到JY61P姿态传感器时&#xff0c;最让人头疼的就是如何从那一串串十六进制数据中提取出可用的姿态信息。作为一款性价比极高的六轴传感器模块&#xff0c;JY61P集成了三轴加速度计和三轴陀螺仪&#xff…...

从GPS到空速计:一文搞懂iNavFlight MSP v2支持的6种传感器数据格式与配置要点

从GPS到空速计&#xff1a;iNavFlight MSP v2传感器数据格式深度解析与实战配置指南 当你在深夜的工作台前调试无人机时&#xff0c;突然发现飞控无法识别新接入的光流传感器——这种场景对DIY玩家来说再熟悉不过了。iNavFlight作为开源飞控系统的佼佼者&#xff0c;其MSP v2协…...

如何构造基于人机环境系统智能中“六三”框架的计算+算计系统

构造一个基于“六三”框架&#xff08;三体、三身、三值、三算、三律、三论&#xff09;的计算算计系统&#xff0c;是一项将哲学思想转化为工程实践的系统工程。这个框架旨在构建一个“增强人而非替代人”的智慧伙伴&#xff0c;实现人机环境的共生与协同。以下是构建该系统的…...

OFD转PDF全攻略:4步解决文档兼容性难题

OFD转PDF全攻略&#xff1a;4步解决文档兼容性难题 【免费下载链接】Ofd2Pdf Convert OFD files to PDF files. 项目地址: https://gitcode.com/gh_mirrors/ofd/Ofd2Pdf 在日常办公和电子文档处理中&#xff0c;我们经常会遇到一个令人头疼的问题&#xff1a;收到的OFD格…...

WPF自定义控件实战:从用户吐槽到优雅实现——我的DateTimePicker开发踩坑记

WPF自定义控件实战&#xff1a;从用户吐槽到优雅实现——我的DateTimePicker开发踩坑记 那天产品经理拍着桌子说&#xff1a;"我们的用户需要精确到秒的时间选择&#xff01;"我看了看系统里那个老旧的DatePicker&#xff0c;只能显示年月日&#xff0c;心里默默叹了…...

从LeGO-LOAM到FAST-LIO2:Patchwork地面分割如何提升SLAM建图与定位精度?

Patchwork地面分割算法在激光SLAM中的实战优化&#xff1a;从原理到性能提升 激光雷达SLAM技术正面临复杂环境下的新挑战——如何从海量点云中快速准确地分离地面点&#xff0c;成为提升建图与定位精度的关键。传统均匀网格划分方法在远距离区域容易失效&#xff0c;而Patchwor…...

渗透基础知识ctfshow——Web应用安全与防护(第六 七章)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录混合型XSSXSS 练习&#xff08;反射型&#xff09;**绕过方法**新增知识&#xff1a;平台外带xss编码绕过XSS过滤绕过方法请求伪造漏洞_CSRF绕过方法最简单的SSRFSSR…...

告别常物性!Fluent材料物性随温度变化的三种设置方法(Piecewise-linear/Polynomial保姆级教程)

Fluent动态物性设置实战&#xff1a;从分段线性到多项式拟合的工程决策指南 在热流体仿真中&#xff0c;材料物性参数往往被简化为常数&#xff0c;这种假设在温度变化剧烈的场景下会带来显著误差。某涡轮叶片冷却分析案例显示&#xff0c;当采用常物性设定时&#xff0c;壁面温…...