Java AIO(NIO.2)
Java AIO(Asynchronous I/O,异步I/O),也被称为NIO.2,是Java平台提供的一种处理异步输入/输出操作的机制。作为Java NIO(New I/O)的扩展,AIO引入了一些新的API和特性,旨在提高I/O操作的效率和响应速度,特别是在处理大量并发连接时。
核心组件
-
异步通道(Asynchronous Channels):
AIO中的异步通道允许应用程序在不阻塞当前线程的情况下启动I/O操作。这些通道包括AsynchronousSocketChannel
、AsynchronousServerSocketChannel
、AsynchronousFileChannel
和AsynchronousDatagramChannel
。它们提供了read
、write
等异步方法,这些方法接受一个ByteBuffer
作为数据缓冲区,并返回一个Future
对象或接受一个CompletionHandler
回调接口来通知操作结果。 -
Future和CompletionHandler:
Future
对象用于表示异步操作的结果。通过调用Future
的get()
方法,应用程序可以等待操作完成并获取结果,但这样做可能会阻塞当前线程。CompletionHandler
接口定义了两个方法:completed(V result, A attachment)
和failed(Throwable exc, A attachment)
。当异步操作成功完成时,会调用completed
方法;当操作失败时,会调用failed
方法。这两个方法都接受一个附件(attachment)参数,该参数是启动异步操作时传递的额外信息。
-
异步组(Asynchronous Groups):
异步组允许应用程序将多个异步通道和相关的资源(如线程池)组合在一起进行管理。AsynchronousChannelGroup
类表示一个异步组的抽象,它提供了启动、关闭和监控组中异步操作的方法。
使用场景
AIO适用于需要处理大量并发连接的高性能网络应用程序,如Web服务器、聊天服务器、在线游戏服务器等。在这些场景中,传统的同步I/O或Java NIO中的非阻塞I/O可能会成为性能瓶颈,因为它们需要为每个连接分配一个线程或处理大量的线程切换。通过使用AIO,应用程序可以重用少量的线程来处理多个并发I/O操作,从而提高性能和可扩展性。
注意事项
- AIO的编程模型比传统的同步I/O和Java NIO中的非阻塞I/O更复杂。它要求开发人员更深入地理解异步编程和事件驱动架构。
- 由于AIO是异步的,因此错误处理和资源清理也变得更加复杂。开发人员需要确保在适当的时机关闭通道、处理异常并释放资源。
- AIO的性能优势在高并发场景下最为明显。在低并发场景下,它可能不如传统的同步I/O或Java NIO中的非阻塞I/O高效。
示例代码
以下是一个简单的AIO服务器示例,它使用AsynchronousServerSocketChannel
来监听连接,并使用CompletionHandler
来处理连接和读取数据:
// 省略了import语句和异常处理
public class AioServer {public static void main(String[] args) {try (AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open()) {serverChannel.bind(new InetSocketAddress(8080));System.out.println("Server started on port 8080");// 创建一个异步组(可选)AsynchronousChannelGroup group = AsynchronousChannelGroup.withFixedThreadPool(10, Executors.defaultThreadFactory());serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {@Overridepublic void completed(AsynchronousSocketChannel clientChannel, Void attachment) {// 处理新连接ByteBuffer buffer = ByteBuffer.allocate(1024);clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result, ByteBuffer attachment) {attachment.flip();byte[] bytes = new byte[attachment.remaining()];attachment.get(bytes);String message = new String(bytes);System.out.println("Received: " + message);// 处理接收到的数据(例如,回显给客户端)ByteBuffer responseBuffer = ByteBuffer.wrap(("Echo: " + message).getBytes());clientChannel.write(responseBuffer).addListener(new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer result, Void attachment) {// 关闭客户端通道try {clientChannel.close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, Void attachment) {System.err.println("Write failed: " + exc.getMessage());try {clientChannel.close();} catch (IOException e) {e.printStackTrace();}}}, null);// 准备接受下一个读取操作buffer.clear();clientChannel.read(buffer, buffer, this);}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.err.println("Read failed: " + exc.getMessage());try {clientChannel.close();} catch (IOException e) {e.printStackTrace();}}});// 准备接受下一个连接serverChannel.accept(null, this);}@Overridepublic void failed(Throwable exc, Void attachment) {System.err.println("Accept failed: " + exc.getMessage());}}, null);// 如果创建了异步组,则需要在服务器关闭时关闭它// group.shutdownNow(); // 注意:这个调用应该在适当的时候进行,例如在服务器停止时// 由于示例中使用了try-with-resources语句,serverChannel会在main方法结束时自动关闭// 但对于异步组,需要手动管理其生命周期(如果需要的话)// 保持服务器运行(在实际应用中,应该有更优雅的停止机制)Thread.sleep(Long.MAX_VALUE);} catch (IOException | InterruptedException e) {e.printStackTrace();}}
}
注意:上述示例代码中的Thread.sleep(Long.MAX_VALUE);
仅用于保持服务器运行,以便在测试期间接受连接。在实际应用中,你应该实现一个更优雅的停止机制,例如通过监听一个特定的信号或中断来关闭服务器。此外,示例中省略了异常处理和资源清理的完整代码,以确保示例的简洁性。在实际应用中,你应该确保在适当的时机关闭通道、处理异常并释放资源。
相关文章:

Java AIO(NIO.2)
Java AIO(Asynchronous I/O,异步I/O),也被称为NIO.2,是Java平台提供的一种处理异步输入/输出操作的机制。作为Java NIO(New I/O)的扩展,AIO引入了一些新的API和特性,旨在…...

Flink 常用问题及常用配置(有用)
一、Flink 常用问题及常用配置 参数 示例 说明 execution.checkpointing.interval 3min Checkpoint 触发间隔 state.backend rocksdb / filesystem 用于设置statebackend类型, 默认会以内存为statebackend(无法支持大状态) taskmanager.memory.jvm-overhead.max 204…...

RocketMQ: 消息过滤,通信组件,服务发现
消息过滤 1 ) 简单消息过滤 /*** 订阅指定topic下tags分别等于 TagA 或 TagC 或 TagD */consumer.subscribe("TopicTest1", "TagA || TagC || TagD");如以上代码所示,简单消息过滤通过指定多个 Tag 来过滤消息,过滤的动作在服务器进…...

linux ubuntu的脚本知
目录 一、变量的引用 二、判断指定的文件是否存在 三、判断目录是否存在 四、判断最近一次命令执行是否成功 五、一些比较符号 六、"文件"的读取和写入 七、echo打印输出 八、ubuntu切换到root用户 N、其它可以参考的网址 脚本功能强大,用起来也…...

HTTP有哪些风险?是怎么解决的?
一、风险 HTTP是通过明文传输的,存在窃听风险、篡改风险以及冒充风险。 二、如何解决 HTTPS在HTTP的下层加了一个SSL/TLS层,保证了安全,通过混合加密解决窃听风险、数字签名解决篡改风险、数字证书解决冒充风险。 (1࿰…...

3.12MayBeSomeLinearAlgebra
X是M*(D1),XT为(D1)*M Ω是一行D1列,X乘以欧米噶是M行D1列 行是说样本个数,列是特征数量 如果是小样本,那么可能会出现特征数量大于样本个数 如果MD*DM就是M*M,...

学习日志015--python单链表
创建 class Node:def __init__(self,data):# 数据域self.data data# 链接域self.next Noneclass LinkList:def __init__(self,):# 初始化头节点self.head None# 记录链表的长度self.size 0 增加 #头插def insert_head(self,value):# 创建新节点node Node(value)q self…...

如何在Windows右键新建菜单中添加自定义项
Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\.py] "Python.File"[HKEY_CLASSES_ROOT\.py\ShellNew] "NullFile"""[HKEY_CLASSES_ROOT\Python.File] "FriendlyTypeName""文本.py"[HKEY_CLASSES_ROOT\Python.Fil…...

Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE
Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE 历史背景 javax变成Jakarta的主要原因是因为Java EE项目从Oracle转移到了Eclipse Foundation,并改名为Jakarta EE。 JavaEE是从Java 1.2版本开始推出的Java企业级开发平台,最初的名称是J2EE(J…...

pdf文档动态插入文字水印,45度角,旋转倾斜,位于文档中央,多行水印可插入中文
一行水印 /*** param inputFile 你的PDF文件地址* param outputFile 添加水印后生成PDF存放的地址* param waterMarkName 你的水印* return*/public static boolean waterMark(String inputFile,String outputFile, String waterMarkName){try {PdfReader reader new PdfRead…...

[ 渗透测试面试篇-2 ] 针对大规模资产的攻击思路
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

深入解析 Web 应用中的 CHIPS(Partitioned Cookie Attribute)
深入解析 Web 应用中的 CHIPS(Partitioned Cookie Attribute) 最新发现flask3.1.0 的版本引入了新的特性:对CHIPS的支持。不少同学对这个可能有点陌生,本文带大家了解一下。 为了在隐私保护和功能需求之间取得平衡,Goo…...

从搭建uni-app+vue3工程开始
技术栈 uni-app、vue3、typescript、vite、sass、uview-plus、pinia 一、项目搭建 1、创建以 typescript 开发的工程 npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project2、安装sass npm install -D sass// 安装sass-loader,注意需要版本10,…...

归并排序与逆序对问题(C语言版)
一、引言 归并排序是一种高效且稳定的排序方法,而逆序对问题是算法领域的一个经典问题,本文教大家如何实现归并排序,以及如何使用归并排序去结果逆序对问题 二、归并排序 归并排序思想 分解:将待排序的数组分成两半,…...

网络爬虫总结与未来方向
通过深入学习和实际操作,网络爬虫技术从基础到进阶得以系统掌握。本节将全面总结关键内容,并结合前沿技术趋势与最新资料,为开发者提供实用性强的深度思考和方案建议。 1. 网络爬虫技术发展趋势 1.1 趋势一:高性能分布式爬虫 随…...

C++ 核心数据结构:Stack 与 Queue 类深度解析
🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 目录 💯前言 💯Stack 类 (一)Stack 类的概念与特点 (二&#x…...

Python枚举类详解:用enum模块高效管理常量数据
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 在编程中,常量的管理是一个关键环节,合理的管理常量可以提高代码的可读性和可维护性。Python的enum模块提供了一种有效的方式来组织常量数据,通过枚举类(Enum)将相关的常量值集合在一起,使代码更具结…...

企业OA管理系统:Spring Boot技术深度探索
4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…...

汽车免拆诊断案例 | 2012款路虎揽胜运动版柴油车加速无力
故障现象 一辆2012款路虎揽胜运动版车,搭载3.0T柴油发动机(型号为306DT),累计行驶里程约为10.2万km。车主进厂反映,车辆行驶中加速无力,且发动机故障灯异常点亮。 故障诊断 接车后试车,发动…...

uniapp接入高德地图
下面代码兼容安卓APP和H5 高德地图官网:我的应用 | 高德控制台 ,绑定服务选择《Web端(JS API)》 /utils/map.js 需要设置你自己的key和安全密钥 export function myAMap() {return new Promise(function(resolve, reject) {if (typeof window.onLoadM…...

(UI自动化测试)web自动化测试
web自动化测试 UI自动化测试介绍 自动化测试理论: 图片上的文字等等不能做测试,只能发现固定的bug 工具选择及介绍 浏览器驱动:找元素--核心:驱动(操作元素)--通过代码...

【es6进阶】如何使用Proxy实现自己的观察者模式
观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。这里,我们是使用es6的proxy及reflect来实现这个效果。 实现效果 业务分析 源数据 const object2 {name: "张三"…...

住宅IP怎么在指纹浏览器设置运营矩阵账号
矩阵账号的运营已经成为了许多企业和个人推广策略中的重要一环。通过构建和管理多个社交媒体或电商平台的账号,可以有效地扩大品牌影响力,提高市场覆盖率。然而,随着平台对账号关联的限制越来越严格,如何安全、有效地运营这些矩阵…...

表格数据处理中大语言模型的微调优化策略研究
论文地址 Research on Fine-Tuning Optimization Strategies for Large Language Models in Tabular Data Processing 论文主要内容 这篇论文的主要内容是研究大型语言模型(LLMs)在处理表格数据时的微调优化策略。具体来说,论文探讨了以下…...

CentOS7 如何查看kafka topic中的数据
1. 确保 Kafka 服务运行 先检查 Kafka 和 Zookeeper 是否正在运行: systemctl status kafka systemctl status zookeeper 如果没有启动,先启动服务: systemctl start zookeeper systemctl start kafka 2. 进入 Kafka 安装目录 通常 …...

VRRP实现出口网关设备冗余备份
VRRP虚拟路由冗余 vrrp实现设备主备备份 Tips: VRRP能够在不改变组网的情况下,将多台路由器虚拟成一个虚拟路由器,通过配置虚拟路由器的IP地址为默认网关,实现网关的备份。协议版本: VRRPV2 (常用)和VRRPV3:VRRPV2仅适用于IPv4…...

超详细:Redis分布式锁
如何基于 Redis 实现一个最简易的分布式锁? 不论是本地锁还是分布式锁,核心都在于“互斥”。 在 Redis 中, SETNX 命令是可以帮助我们实现互斥。SETNX 即 SET if Not eXists (对应 Java 中的 setIfAbsent 方法),如果 key 不存在…...

Vue与React的Suspense组件对比
在Vue和React中都内置了Suspense组件,该组件用于处理异步组件加载。当Suspense包裹的实际组件内容尚未加载完成时会先展示后备内容,等待组件内容加载完成后再切换成实际组件内容。这可以显著提升用户体验,适用于大数据加载、组件懒加载等场景…...

Spring框架深度剖析:特性、安全与优化
文章目录 Spring框架简介主要特性1. 依赖注入(Dependency Injection, DI)2. 面向切面编程(Aspect-Oriented Programming, AOP)3. 声明式事务管理4. 强大的MVC框架5. 集成测试支持6. 多种数据访问技术的支持 安全性1. 认证…...

硬盘文件误删:全面解析、恢复方案与预防策略
一、硬盘文件误删现象概述 在日常使用电脑的过程中,硬盘文件误删是许多用户都曾遇到过的问题。这种意外的数据丢失,不仅可能让我们辛苦编辑的文档、珍贵的照片和视频等瞬间消失,还可能对工作和生活造成重大影响。硬盘文件误删,如…...