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

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...