【Netty】Future 源码分析(十六)
文章目录
- 前言
- 一、JDK 的 Future 接口
- 二、Netty 的 Future 接口
- 三、ChannelFuture 接口
- 总结
前言
回顾Netty系列文章:
- Netty 概述(一)
- Netty 架构设计(二)
- Netty Channel 概述(三)
- Netty ChannelHandler(四)
- ChannelPipeline源码分析(五)
- 字节缓冲区 ByteBuf (六)(上)
- 字节缓冲区 ByteBuf(七)(下)
- Netty 如何实现零拷贝(八)
- Netty 程序引导类(九)
- Reactor 模型(十)
- 工作原理详解(十一)
- Netty 解码器(十二)
- Netty 编码器(十三)
- Netty 编解码器(十四)
- 自定义解码器、编码器、编解码器(十五)
JDK 中提供了 Future 接口,Future 代表了一个异步处理的结果。
Netty 中对 JDK 的 Future 做了扩展。
为了深入了解这两者的不同点,下面我们就来分析这两者的源码。
一、JDK 的 Future 接口
Future 接口提供了一些方法检查是否计算完毕,例如,等待计算完毕,获取计算结果的方法。当计算完毕之后只能通过 get 方法获取结果,或者一直阻塞等待计算的完成。取消操作可以通过 cancel 方法。另外也提供了 isDone 方法,用于检测是正常完成还是被取消终止。
需要注意的是,当 Future 的计算完成后,不能进行取消操作。
Future 的核心源码如下:
public interface Future<V> {/*** 用来取消任务,取消成功则返回true,取消失败则返回false。* mayInterruptIfRunning参数表示是否允许取消正在执行却没有执行完毕的任务,设为true,则表示可以取消正在执行过程中的任务。* 如果任务已完成,则无论mayInterruptIfRunning为true还是false,此方法都返回false,即如果取消已经完成的任务会返回false;* 如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;* 如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。*/boolean cancel(boolean mayInterruptIfRunning);/*** 表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回true*/boolean isCancelled();/*** 表示任务是否已经完成,若任务完成,则返回true*/boolean isDone();/*** 获取执行结果,如果最终结果还没得出该方法会产生阻塞,直到任务执行完毕返回结果*/V get() throws InterruptedException, ExecutionException;/*** 获取执行结果,如果在指定时间内,还没获取到结果,则抛出TimeoutException*/V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}
在上面的接口定义中可以知道,jdk 中的 Future 无论结果是成功、失败还是取消,都用 isdone() 来检测,而且无法区分到底是正常成功了,还是异常终止了。因此在 Netty 中对 jdk 的 Future 做了扩展。
二、Netty 的 Future 接口
核心源码如下:
public interface Future<V> extends java.util.concurrent.Future<V> {//异步操作完成且正常终止boolean isSuccess();//异步操作是否可以取消boolean isCancellable();//异步操作失败的原因Throwable cause();//添加一个监听,异步操作完成时调用Future<V> addListener(GenericFutureListener<? extends Future<? super V>> var1);Future<V> addListeners(GenericFutureListener<? extends Future<? super V>>... var1);//移除监听者Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> var1);Future<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... var1);//阻塞直到异步操作完成Future<V> sync() throws InterruptedException;Future<V> syncUninterruptibly();//阻塞直到异步操作完成Future<V> await() throws InterruptedException;Future<V> awaitUninterruptibly();boolean await(long var1, TimeUnit var3) throws InterruptedException;boolean await(long var1) throws InterruptedException;boolean awaitUninterruptibly(long var1, TimeUnit var3);boolean awaitUninterruptibly(long var1);//非阻塞地返回异步结果,如果尚未完成返回 nullV getNow();boolean cancel(boolean var1);
}
Netty 中的 Future 相对于jdk 中的 Future 做了以下几个方面的扩展。
操作完成的结果做了区分,分为 sucess 、fail、canceled 三种。
通过 addListeners() 方法可以添加回调操作,即触发或者完成时需要进行的操作。
sync()和await(),可以以阻塞的方式等待异步完成。
getNow() 可以获取异步操作的结果,如果还未完成则返回 null 。
三、ChannelFuture 接口
在 Netty 中,ChannelFuture 表示 Channel 的异步 I/O 操作的结果。
ChannelFuture 的核心源码如下:
public interface ChannelFuture extends Future<Void> {Channel channel();ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> var1);ChannelFuture addListeners(GenericFutureListener<? extends Future<? super Void>>... var1);ChannelFuture removeListener(GenericFutureListener<? extends Future<? super Void>> var1);ChannelFuture removeListeners(GenericFutureListener<? extends Future<? super Void>>... var1);ChannelFuture sync() throws InterruptedException;ChannelFuture syncUninterruptibly();ChannelFuture await() throws InterruptedException;ChannelFuture awaitUninterruptibly();boolean isVoid();
}
从上述源码可以看到,ChannelFuture 接口基本上继承自 Netty 的 Future 接口。
在 Netty 中所有的 I/O 操作都是异步的,意味着很多的 I/O 操作被调用过后会立刻返回,并且不能保证 I/O请求操作被调用后计算完毕,替代它的是返回一个当前 I/O 操作状态和结果信息的 ChannelFuture 实例。
一个 ChannelFuture 要么是完成的,要么是未完成的。当一个 I/O 操作开始时,会创建一个 Future 对象,Future 初始化时为完成的状态,它既不是成功,也不是失败,也不是被取消。因为 I/O 操作还没有完全结束。如果 I/O 操作已经完成,那它要么是成功,要么是失败,要么是被取消,这个 future 会被标记成已完成并伴随其他信息,比如失败的原因。
下图展示了 ChannelFuture 从未完成到完成的所有场景的状态变化。
+---------------------------+| Completed successfully |+---------------------------++----> isDone() = true |+--------------------------+ | | isSuccess() = true || Uncompleted | | +===========================++--------------------------+ | | Completed with failure || isDone() = false | | +---------------------------+| isSuccess() = false |----+----> isDone() = true || isCancelled() = false | | | cause() = non-null || cause() = null | | +===========================++--------------------------+ | | Completed by cancellation || +---------------------------++----> isDone() = true || isCancelled() = true |+---------------------------+
ChannelFuture 提供了各种各样的方法来检查 I/O 操作是否已完成,等待完成,返回 I/O 操作的结果。同时,也能让你增加ChannelFutureListener,这样当 I/O 操作完成的时候,你就能获得通知。
推荐优先使用addListener(GenericFutureListener)方法,而不是await()方法。在可能的情况下,这样就能在 I/O 操作完成时收到通知,并且可以去做后续的任务处理。 addListener(GenericFutureListener) 本身是非阻塞的,它会添加一个指定的ChannelFutureListener 到ChannelFuture,并且 I/O 线程完成对应的操作将会通知监听器,ChannelFutureListener也会提供最好的性能和资源利用率,因为它永远不会阻塞,但是如果不是基于事件编程,它可能在顺序逻辑上存在棘手的问题。
相反的,await()是一个阻塞的操作,一旦被调用,调用者线程在操作完成之前的阻塞的。
总结
以上我们分析了 JDK 提供的 Future 以及 Netty 的 Future 接口,下节我们来分析 Netty 中的 Promise,Promise是可写的 Future, Future 自身并没有写操作相关的接, Netty 通过 Promise对 Future进行扩展,用于设置 I/O 操作的结果。
相关文章:
【Netty】Future 源码分析(十六)
文章目录 前言一、JDK 的 Future 接口二、Netty 的 Future 接口三、ChannelFuture 接口总结 前言 回顾Netty系列文章: Netty 概述(一)Netty 架构设计(二)Netty Channel 概述(三)Netty Channel…...
5月《中国数据库行业分析报告》正式发布,首发时序、实时数据库两大【全球产业图谱】
为了帮助大家及时了解中国数据库行业发展现状、梳理当前数据库市场环境和产品生态等情况,从2022年4月起,墨天轮社区行业分析研究团队出品将持续每月为大家推出最新《中国数据库行业分析报告》,持续传播数据技术知识、努力促进技术创新与行业生…...
【计算机视觉 | 目标检测】术语理解6:ViT 变种( ViT-H、ViT-L ViT-B)、bbox(边界框)、边界框的绘制(含源代码)
文章目录 一、ViT & ViT变种1.1 ViT的介绍1.2 ViT 的变种 二、bbox(边界框)三、边界框的绘制 一、ViT & ViT变种 1.1 ViT的介绍 ViT,全称为Vision Transformer,是一种基于Transformer架构的视觉处理模型。传统的计算机视…...
为kong网关添加限流插件
限流用于控制发送到上游服务的请求速率。 它可用于防止 DoS 攻击、限制网络抓取和其他形式的过度使用。 如果没有速率限制,客户可以无限制地访问您的上游服务,这可能会对可用性产生负面影响。 一、全局范围内的限流 1、启用限流 [rootmin ~]# curl -i…...
Python接口自动化—接口测试用例和接口测试报告模板
简介 当今社会在测试领域,接口测试已经越来越多的被提及,被重视,而且现在好多招聘信息要对接口测试提出要求。区别于传统意义上的系统级别测试,很多测试人员在接触到接口测试的时候,也许对测试执行还可以比较顺利的上…...
C++无锁队列
C无锁队列是一种多线程编程技术,它可以在不使用锁的情况下实现线程安全的队列。它可以提高多线程程序的性能。 无锁队列的主要思想是让多个线程同时访问队列,而不需要使用锁来保护共享资源。这可以避免锁竞争和死锁等问题,从而提高程序的效率…...
MySQL 5.7 修改账号密码
MySQL 5.7 修改账号密码 1、概述2、更改密码2.1、寻找命令2.2、补充 3、总结 1、概述 大家好,我是欧阳方超。 MySQL数据库安装后设置的密码太简单了, 近期安全检查,这种弱密码全部得修改,好吧那就开始改吧 2、更改密码 2.1、寻…...
ARM实验6-基于中断的按键处理程序实验
一、实验名称:基于中断的按键处理程序实验 二、实验目的: 1.掌握ARM处理器的中断处理过程。 2.掌握ARM处理器中断服务程序的编写方法。 3.通过该编程实验,进一步巩固和强化学生ARM汇编编程的能,ARM应用程序框架,培养学生实际应用的能力。 三、实验内容: 按下面电路图,…...
安全认证:
1. 认证概述 为什么要有认证? 防止非法路由器接入企业内网的ospf路由器,保护内网安全 2. 认证方式 认证方式分为接口认证和区域认证,接口认证和区域认证没有本质的区别,接口认证是当区域内链路过多的情况下,接口认证…...
C++11新特性:decltype类型推导
上一节所讲的 auto,用于通过一个表达式在编译时确定待定义的变量类型,auto 所修饰的变量必须被初始化,编译器需要通过初始化来确定 auto 所代表的类型,即必须要定义变量。若仅希望得到类型,而不需要(或不能)定义变量的…...
linux下DD 命令常用操作 —— 筑梦之路
DD命令介绍 dd命令是LINUX下的一个命令行工具,用于数据转换和处理。dd代表“数据复制”,它可以从一个设备或文件中读取数据,然后将数据写入到另一个设备或文件中。dd命令可以用于多种用途,包括以下几个方面: 磁盘备份…...
android 12.0状态栏高度为0时,系统全局手势失效的解决方案
1.概述 在12.0的framework 系统全局手势事件也是系统非常重要的功能,但是当隐藏状态栏, 当把状态栏高度设置为0时,这时全局手势事件失效,这就要从系统手势滑动流程来分析 看怎么样实现系统手势功能的,然后根据功能做修改 2. 状态栏高度为0时,系统全局手势失效的解决方案…...
使用Jmeter进行http接口性能测试
在进行网页或应用程序后台接口开发时,一般要及时测试开发的接口能否正确接收和返回数据,对于单次测试,Postman插件是个不错的Http请求模拟工具。 但是Postman只能模拟单客户端的单次请求,而对于模拟多用户并发等性能测试…...
公开报名|CCPTP云渗透测试认证专家第二期培训班,将在云网基础设施安全国家工程研究中心举办
CCPTP云渗透测试认证专家由云安全联盟大中华区发布,是全球首个云渗透测试能力培养课程及人才培养认证,弥补了国内云渗透测试认知的差距和技能型人才培养的空白。4月1日-13日,CCPTP 首期班成功举办,于2023年5月10日部分学员完成考试…...
【App自动化测试】(十八)多设备管理平台——openSTF
目录 1. openSTF2. openSTF的安装部署2.1 MacOS2.2 Windows 3. STF操作3.1 基础操作——远程调试虚拟设备3.2 高阶操作——远程调试真机 1. openSTF OpenSTF:是一个手机设备管理平台,可以对手机进行远程管理、调试、远程手机桌面监控等操作。 特点&…...
Kafka的ACK配置含义详解
Kafka的ACK配置含义详解 Kafka producer有三种ack机制 初始化producer时在config中进行配置; 参数-1,0,1分别代表什么含义 ack等于0: 含义 意味着producer不等待broker同步完成的确认,只要继续发送下一条(批)信息 优缺点 提供了最低的…...
Redis主从架构、数据同步原理、全量同步、增量同步
目录 专栏导读一、Redis主从架构二、数据同步原理三、全量同步的流程三、可以从以下几个方面来优化Redis主从就集群四、全量同步和增量同步区别?五、什么时候执行全量同步?六、什么时候执行增量同步?七、超卖问题 大家好,我是哪吒…...
面了一个测试工程师要求月薪26K,总感觉他背了很多面试题...
最近有朋友去字节面试,面试前后进行了20天左右,包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说,80%的人都会栽在第一轮面试,要不是他面试前做足准备,估计都坚持不完后面几轮面试。 其实&…...
大数据简介
大数据简介 什么是大数据 最近几年,IT行业最火的名词中,少不了"大数据"、"人工智能"、"云计算"、"物联网"、"区块链"等等这些名词。针对于"大数据"这个名词,现在更是全国老…...
Elasticsearch数据库
目录 1. 什么是ElasticSearch1.1 概念及特点1.2 ElasticSearch适用场景概述 2. 安装ElasticSearch2.1 下载安装包2.2 环境说明2.3 创建es的用户2.4 创建es存储位置2.5 安装es2.5 修改配置文件2.6 系统优化2.7 安装jdk环境2.8 切换es用户启动数据库2.9 systemctl管理2.10 访问 3…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
