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

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初&#xff0c;人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目&#xff08;一款融合大型语言模型能力的云端AI编程IDE&#xff09;时&#xff0c;技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力&#xff0c;TRAE在WayToAGI等…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL&#xff08;Software OpenGL&#xff09;‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式&#xff08;包括几何处理、光栅化、着色等&#xff09;&#xff0c;不依赖GPU硬件加速。这种模式通常性能较低&#xff0c;但兼容性极强&#xff0c;常用于不支持硬件加速…...