当前位置: 首页 > 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软件平台上…...

Jetson Orin Nano 升级jetpack5.1.2刷机过程记录

一.刷机起因 orin nano 接了个IMX477的摄像头,用 命令行DISPLAY:0.0 nvgstcapture-1.0 显示的画面有撕裂,让卖家查问题,卖家测试没有撕裂,对比环境,orin nano出厂默认的是jetpack5.1.1,卖家用的jetpack5.1.2版本,为了解决差异,要升级jetpack版本,前后搞了2天半,记录一下. 另外…...

Redis沙盒体验:在浏览器中零门槛掌握NoSQL核心技能

Redis沙盒体验&#xff1a;在浏览器中零门槛掌握NoSQL核心技能 【免费下载链接】try.redis A demonstration of the Redis database. 项目地址: https://gitcode.com/gh_mirrors/tr/try.redis 当你第一次听说Redis时&#xff0c;是否被那些晦涩的技术术语吓退&#xff1…...

【2026最新】应对Turnitin查重:实测5大英文查降AI宝藏工具,一站式搞定初稿

现在的英文初稿&#xff0c;无论是期刊文章、SCI 还是普通的 Course Essay&#xff0c;基本都需要评估内容的原创度&#xff0c;进行文章 AI 率检测。很多伙伴以为纯手敲就能过&#xff0c;结果一查数据依然不尽如人意。 针对英文内容&#xff0c;咱们必须使用专门的英文检测和…...

告别手写UI!用NXP GUI Guider拖拽设计LVGL界面,5分钟搞定音乐播放器Demo

嵌入式UI开发革命&#xff1a;5分钟用GUI Guider构建LVGL音乐播放器在嵌入式系统开发中&#xff0c;用户界面(UI)设计曾长期是工程师的痛点——既要考虑资源受限的硬件环境&#xff0c;又要实现流畅美观的交互体验。传统手动编写UI代码的方式不仅效率低下&#xff0c;调试过程更…...

【UniApp小程序开发】解决无法使用Vue自定义指令的完美替代方案:权限组件封装

在 UniApp 开发中&#xff0c;你是否遇到过这样的困惑&#xff1a;明明在 Vue Web 项目中用得顺手的 v-permission 自定义指令&#xff0c;一到小程序端就完全失效&#xff1f;本文将深入剖析其原因&#xff0c;并提供一套可直接复用的组件化解决方案&#xff0c;让你在小程序中…...

3分钟掌握HashCalculator:你的文件完整性守护专家

3分钟掌握HashCalculator&#xff1a;你的文件完整性守护专家 【免费下载链接】HashCalculator 哈希值计算工具&#xff0c;批量计算/批量校验/查找重复文件/改变哈希值等&#xff0c;支持集成到系统右键菜单 项目地址: https://gitcode.com/gh_mirrors/ha/HashCalculator …...

PCB虚焊/走线断裂/焊盘脱落工程师易漏判

PCB 故障中&#xff0c;30% 并非元件损坏&#xff0c;而是 PCB 本身的隐性故障—— 虚焊、走线断裂、焊盘脱落、过孔开路。这类故障外观隐蔽、时好时坏、排查难度大&#xff0c;很多工程师反复更换元件仍无法解决&#xff0c;最终误判为 “板报废”。​一、PCB 隐性故障核心成因…...

Graphin高级应用:结合GISDK构建配置化图分析模块的完整指南

Graphin高级应用&#xff1a;结合GISDK构建配置化图分析模块的完整指南 【免费下载链接】Graphin &#x1f30c; A React toolkit for graph visualization based on G6. 项目地址: https://gitcode.com/gh_mirrors/gr/Graphin 在当今数据驱动的时代&#xff0c;图可视化…...

GIS工程应用记录(AI辅助编程)

问题的问题&#xff1a;语境坍缩“从各个角度提出问题&#xff0c;AI做出对应积极答复和修改&#xff0c;结果没有什么变化。”这&#xff0c;就是元问题最核心的症状。你尝试了所有你已知的“高级”协作手段&#xff0c;但就像重拳打在棉花上&#xff0c;AI永远在积极回应&…...

树莓派工业GPIO接口板:电气隔离与电平转换实战指南

1. 项目概述&#xff1a;为什么需要一块工业级GPIO接口板&#xff1f;如果你用树莓派做过一些硬件项目&#xff0c;尤其是涉及到控制继电器、电机或者连接工业设备&#xff08;比如PLC、变频器&#xff09;时&#xff0c;大概率踩过这样的坑&#xff1a;直接用树莓派的GPIO引脚…...