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

【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系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设计&#xff08;二&#xff09;Netty Channel 概述&#xff08;三&#xff09;Netty Channel…...

5月《中国数据库行业分析报告》正式发布,首发时序、实时数据库两大【全球产业图谱】

为了帮助大家及时了解中国数据库行业发展现状、梳理当前数据库市场环境和产品生态等情况&#xff0c;从2022年4月起&#xff0c;墨天轮社区行业分析研究团队出品将持续每月为大家推出最新《中国数据库行业分析报告》&#xff0c;持续传播数据技术知识、努力促进技术创新与行业生…...

【计算机视觉 | 目标检测】术语理解6:ViT 变种( ViT-H、ViT-L ViT-B)、bbox(边界框)、边界框的绘制(含源代码)

文章目录 一、ViT & ViT变种1.1 ViT的介绍1.2 ViT 的变种 二、bbox&#xff08;边界框&#xff09;三、边界框的绘制 一、ViT & ViT变种 1.1 ViT的介绍 ViT&#xff0c;全称为Vision Transformer&#xff0c;是一种基于Transformer架构的视觉处理模型。传统的计算机视…...

为kong网关添加限流插件

限流用于控制发送到上游服务的请求速率。 它可用于防止 DoS 攻击、限制网络抓取和其他形式的过度使用。 如果没有速率限制&#xff0c;客户可以无限制地访问您的上游服务&#xff0c;这可能会对可用性产生负面影响。 一、全局范围内的限流 1、启用限流 [rootmin ~]# curl -i…...

Python接口自动化—接口测试用例和接口测试报告模板

简介 当今社会在测试领域&#xff0c;接口测试已经越来越多的被提及&#xff0c;被重视&#xff0c;而且现在好多招聘信息要对接口测试提出要求。区别于传统意义上的系统级别测试&#xff0c;很多测试人员在接触到接口测试的时候&#xff0c;也许对测试执行还可以比较顺利的上…...

C++无锁队列

C无锁队列是一种多线程编程技术&#xff0c;它可以在不使用锁的情况下实现线程安全的队列。它可以提高多线程程序的性能。 无锁队列的主要思想是让多个线程同时访问队列&#xff0c;而不需要使用锁来保护共享资源。这可以避免锁竞争和死锁等问题&#xff0c;从而提高程序的效率…...

MySQL 5.7 修改账号密码

MySQL 5.7 修改账号密码 1、概述2、更改密码2.1、寻找命令2.2、补充 3、总结 1、概述 大家好&#xff0c;我是欧阳方超。 MySQL数据库安装后设置的密码太简单了&#xff0c; 近期安全检查&#xff0c;这种弱密码全部得修改&#xff0c;好吧那就开始改吧 2、更改密码 2.1、寻…...

ARM实验6-基于中断的按键处理程序实验

一、实验名称:基于中断的按键处理程序实验 二、实验目的: 1.掌握ARM处理器的中断处理过程。 2.掌握ARM处理器中断服务程序的编写方法。 3.通过该编程实验,进一步巩固和强化学生ARM汇编编程的能,ARM应用程序框架,培养学生实际应用的能力。 三、实验内容: 按下面电路图,…...

安全认证:

1. 认证概述 为什么要有认证&#xff1f; 防止非法路由器接入企业内网的ospf路由器&#xff0c;保护内网安全 2. 认证方式 认证方式分为接口认证和区域认证&#xff0c;接口认证和区域认证没有本质的区别&#xff0c;接口认证是当区域内链路过多的情况下&#xff0c;接口认证…...

C++11新特性:decltype类型推导

上一节所讲的 auto&#xff0c;用于通过一个表达式在编译时确定待定义的变量类型&#xff0c;auto 所修饰的变量必须被初始化&#xff0c;编译器需要通过初始化来确定 auto 所代表的类型&#xff0c;即必须要定义变量。若仅希望得到类型&#xff0c;而不需要(或不能)定义变量的…...

linux下DD 命令常用操作 —— 筑梦之路

DD命令介绍 dd命令是LINUX下的一个命令行工具&#xff0c;用于数据转换和处理。dd代表“数据复制”&#xff0c;它可以从一个设备或文件中读取数据&#xff0c;然后将数据写入到另一个设备或文件中。dd命令可以用于多种用途&#xff0c;包括以下几个方面&#xff1a; 磁盘备份…...

android 12.0状态栏高度为0时,系统全局手势失效的解决方案

1.概述 在12.0的framework 系统全局手势事件也是系统非常重要的功能,但是当隐藏状态栏, 当把状态栏高度设置为0时,这时全局手势事件失效,这就要从系统手势滑动流程来分析 看怎么样实现系统手势功能的,然后根据功能做修改 2. 状态栏高度为0时,系统全局手势失效的解决方案…...

使用Jmeter进行http接口性能测试

在进行网页或应用程序后台接口开发时&#xff0c;一般要及时测试开发的接口能否正确接收和返回数据&#xff0c;对于单次测试&#xff0c;Postman插件是个不错的Http请求模拟工具。 但是Postman只能模拟单客户端的单次请求&#xff0c;而对于模拟多用户并发等性能测试&#xf…...

公开报名|CCPTP云渗透测试认证专家第二期培训班,将在云网基础设施安全国家工程研究中心举办

CCPTP云渗透测试认证专家由云安全联盟大中华区发布&#xff0c;是全球首个云渗透测试能力培养课程及人才培养认证&#xff0c;弥补了国内云渗透测试认知的差距和技能型人才培养的空白。4月1日-13日&#xff0c;CCPTP 首期班成功举办&#xff0c;于2023年5月10日部分学员完成考试…...

【App自动化测试】(十八)多设备管理平台——openSTF

目录 1. openSTF2. openSTF的安装部署2.1 MacOS2.2 Windows 3. STF操作3.1 基础操作——远程调试虚拟设备3.2 高阶操作——远程调试真机 1. openSTF OpenSTF&#xff1a;是一个手机设备管理平台&#xff0c;可以对手机进行远程管理、调试、远程手机桌面监控等操作。 特点&…...

Kafka的ACK配置含义详解

Kafka的ACK配置含义详解 Kafka producer有三种ack机制 初始化producer时在config中进行配置&#xff1b; 参数-1,0,1分别代表什么含义 ack等于0&#xff1a; 含义 意味着producer不等待broker同步完成的确认&#xff0c;只要继续发送下一条(批)信息 优缺点 提供了最低的…...

Redis主从架构、数据同步原理、全量同步、增量同步

目录 专栏导读一、Redis主从架构二、数据同步原理三、全量同步的流程三、可以从以下几个方面来优化Redis主从就集群四、全量同步和增量同步区别&#xff1f;五、什么时候执行全量同步&#xff1f;六、什么时候执行增量同步&#xff1f;七、超卖问题 大家好&#xff0c;我是哪吒…...

面了一个测试工程师要求月薪26K,总感觉他背了很多面试题...

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…...

大数据简介

大数据简介 什么是大数据 ​ 最近几年&#xff0c;IT行业最火的名词中&#xff0c;少不了"大数据"、"人工智能"、"云计算"、"物联网"、"区块链"等等这些名词。针对于"大数据"这个名词&#xff0c;现在更是全国老…...

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…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...