Java I/O 模型之 AIO

article/2025/9/13 20:14:02

❤️ 个人主页:水滴技术
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬
🌸 订阅专栏:Java 教程:从入门到精通

大家好,我是水滴~~

文章目录

  • 服务端API
    • 创建服务端套接字的异步通道
    • 接收客户端连接
    • 读取客户端数据
  • 客户端API
    • 创建客户端套接字的异步通道
    • 连接服务端
    • 向服务端写入数据

服务端API

创建服务端套接字的异步通道

Java AIO为我们提供了AsynchronousServerSocketChannel类,它是一个面向流监听套接字的异步通道,可以通过该类的open方法创建一个实例。

新创建的异步服务器套接字通道还没有绑定本地地址(IP地址+端口),通过bind方法来绑定一个本地地址,并且启动了监听。此时客户端已经可以连接了。

该通道是线程安全的,但同时只能有一个ACCEPT操作是进行中的。如果前一个线程还未完成ACCEPT操作,后一个线程发起ACCEPT操作,将会抛出AcceptPendingException异常。

// 打开一个异步的 ServerSocket 通道
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
// 绑定本地地址
serverSocketChannel.bind(new InetSocketAddress(8080));

接收客户端连接

AsynchronousServerSocketChannel类提供了两个accept方法,它们都是异步的,不会阻塞。下面我们使用带参数的方法来完成ACCEPT操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cjc62Af8-1649771737856)(https://secure2.wostatic.cn/static/gBmK7M8b6tGTcXMUaRJb8L/image.png)]

第一个参数是要附加到I/O操作的对象,可以为null

第二个参数是一个连接的结果处理器,即当有连接完成后,会自动调用该处理器CompletionHandler,来执行后面的内容。该处理器是一个泛型接口,第一个泛型类型是AsynchronousSocketChannel类,第二个泛型类型是前面提到的附加对象。

下面的示例代码,我们将AsynchronousServerSocketChannel对象做为附加对象,并使用函数式编程来创建CompletionHandler接口的实现。

CompletionHandler接口有两个方法需要我们来实现,completed方法用于客户端连接完成时调用;failed用于客户端连接失败时调用。

不管连接是成功还是失败,都要继续接收下一个连接,以保证服务端的工作。

// 接收客户端连接
serverSocketChannel.accept(serverSocketChannel, new CompletionHandler<AsynchronousSocketChannel, AsynchronousServerSocketChannel>() {@Overridepublic void completed(AsynchronousSocketChannel result, AsynchronousServerSocketChannel attachment) {try {// 一个客户端连接后,继续接收下一个连接attachment.accept(attachment, this);// 申请一个1024个字节的缓冲区ByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 读取客户端数据result.read(byteBuffer, byteBuffer, new ReadCompletionHandler(result));} catch (IOException e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, AsynchronousServerSocketChannel attachment) {// 一个客户端连失败,继续接收下一个连接attachment.accept(attachment, this);}
});

读取客户端数据

AsynchronousServerSocketChannel通道只负责监听客户端连接。当连接建立成功后,会为该连接创建一个AsynchronousSocketChannel 通道,后续服务端与该客户端的I/O操作,都是通过该通道完成的。

该类的read方法用来读取客户端数据,此方法的第一个参数为ByteBuffer缓冲区,第二个参数为附加对象,第三个参数是读取数据的结果处理器。

在这里插入图片描述

该方法启动了一个异步读取操作,会将一个字节序列从该通道中读入给定的缓冲区中。处理程序是一个在读取操作完成(或失败)时调用的结果处理程序。当读取操作完成后,会传递一个读取的字节数,如果通道中流结束(另一端关闭通道),则字节数为-1。

在下面的代码示例中,为读取结果的处理程序创建了一个实现类ReadCompletionHandler,该类的构造方法传入AsynchronousSocketChannel实例,用来读取该通道中数据。

该类在读取完成缓冲区中数据后,会继续调用read方法,来继续读取下一报文。

static class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {private final AsynchronousSocketChannel asynchronousSocketChannel;ReadCompletionHandler(AsynchronousSocketChannel asynchronousSocketChannel) {this.asynchronousSocketChannel = asynchronousSocketChannel;}@Overridepublic void completed(Integer result, ByteBuffer attachment) {// 客户端关闭通道,字节数为-1if(result == -1) {System.out.printf("[%s] - 客户端断开连接!\n", Thread.currentThread().getName());try {// 关闭当前 Socket 通道asynchronousSocketChannel.close();} catch (IOException e) {e.printStackTrace();}return;}// 将缓冲区进行反转(刚才是写入,反转后变为读取)attachment.flip();// 读取缓冲区中的内容,并转为字符串String content = new String(attachment.array(), 0, result);System.out.printf("[%s] - 接收客户端发来的内容:%s\n", Thread.currentThread().getName(), content);// 清除缓冲区attachment.clear();// 继续读取下一报文asynchronousSocketChannel.read(attachment, attachment, new ReadCompletionHandler(asynchronousSocketChannel));}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.out.printf("[%s] - 客户端断开连接!\n", Thread.currentThread().getName());try {// 关闭当前 Socket 通道asynchronousSocketChannel.close();} catch (IOException e) {e.printStackTrace();}}
}

客户端API

创建客户端套接字的异步通道

客户端可以通过AsynchronousSocketChannelopen静态方法,来创建一个异步通道。

// 打开一个异步的 Socket 通道
AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();

连接服务端

该异步通道通过connect方法来连接指定的服务端地址(IP地址+端口),该connect方法也是一个异步方法,同样可以指定结果处理器,但这次我们使用Future方式来实现。

Future是非阻塞的,可以通过isDone方法来检测是否执行完毕。在这里,我们使用get方法来阻塞获取结果,直到连接成功。

// 连接指定的服务端,并同步获取连接结果。
Future<Void> connectFuture = socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080));
// get()操作会阻塞,直到连接成功。
connectFuture .get();

向服务端写入数据

连接成功后,可以向该通道写入数据了。同样write方法也是一个异步的,这里我们也使用Future方式,并通过get方法阻塞获取结果。

// 申请一个1024字节的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
// 将控制台输入的内容写入缓冲区
byteBuffer.put("你好".getBytes());
// 反转缓冲区(从写入变为读取)
byteBuffer.flip();
// 将缓冲区中的内容写入到 Socket 通道中。get()操作会阻塞,直到写入成功。
socketChannel.write(byteBuffer).get();
// 清除缓冲区
byteBuffer.clear();

http://chatgpt.dhexx.cn/article/8lgcp072.shtml

相关文章

如何用AIO技术提高程序性能

写在前面 这是一篇关于 AIO 的文章。本篇文章详细对比了几个常见的I/O模型&#xff0c;并且介绍了AIO相关的一些API。 我把英文原文翻译过来整理成这篇文章。目的一个是自己学习&#xff0c;一个是方便不习惯看英文资料的同学进行学习。 英文原文地址&#xff1a; https://…

08【AIO编程】

八、AIO编程 8.1 AIO编程简介 8.1.1 AIO编程概述 AIO也叫异步非阻塞&#xff0c;JDK1.7之后的新特性&#xff0c;AIO引入异步通道的概念&#xff0c;采用了 Proactor 模式&#xff0c;简化了程序编写&#xff0c;有效的请求才启动线程&#xff0c;它的特点是先由操作系统完成…

linux aio进程简介,Linux AIO机制

Linux的I/O机制经历了一下几个阶段的演进&#xff1a; 1. 同步阻塞I/O: 用户进程进行I/O操作&#xff0c;一直阻塞到I/O操作完成为止。 2. 同步非阻塞I/O: 用户程序可以通过设置文件描述符的属性O_NONBLOCK&#xff0c;I/O操作可以立即返回&#xff0c;但是并不保证I/O操作成功…

关于aio

AIO 是异步非阻塞 同步意味着&#xff0c;在进行读写操作时&#xff0c;线程需要等待结果&#xff0c;还是相当于闲置 异步意味着&#xff0c;在进行读写操作时&#xff0c;线程不必等待结果&#xff0c;而是将来由操作系统来通过回调方式由另外的线程来获得结果 AIO的read方…

linux AIO

AIO 是 Linux 下的异步读写模型&#xff0c;它是 2.6 内核提供的一个标准增强特性。对于文件的读写&#xff0c;即使以 O_NONBLOCK 方式来打开一个文件&#xff0c;也会处于 “阻塞” 状态&#xff0c;因为文件时时刻刻处于可读状态&#xff0c;而从磁盘到内存所等待的时间是惊…

AIO模型

目录 AIO模型介绍 AsynchronousServerSocketChannel&#xff1a;AIO中网络通信服务端的socket 1、future方法 2、callback回调方式 AIO 的回调方式编程 BIO、NIO、AIO的比较 1、释义 BIO&#xff1a;同步阻塞IO模型 NIO&#xff1a;同步非阻塞IO模型 AIO&#xff1a;…

java中IO模型-AIO模型

AIO模型介绍 AIO&#xff08;Asynchronous I/O&#xff09; 异步非阻塞模型&#xff0c; 在javajdk.17版本开始支持AIO&#xff0c;AIO模型需要操作系统的支持。 AIO最大的特性是异步能力&#xff0c;对socket和I/O起作用。 异步IO模型类似的 与NIO模型不同&#xff0c;读写操…

架构解密从分布式到微服务:深入理解网络,AIO

AIO AIO是I/O模型里一个很高的层次&#xff0c;体现了大道至简的软件美学理念。与NIO相比&#xff0c;AIO的框架和使用方法相对简单很多。 AIO包括两大部分:AIO Files解决了文件的异步处理问题&#xff0c;AIO Sockets解决了Socket的异步处理问题。AIO的核心概念为应用发起非…

BIO,NIO,AIO区别

BIO,NIO,AIO 总结 Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候&#xff0c;不需要关心操作系统层面的知识&#xff0c;也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。 在讲 BIO,NIO,…

Apache CXF - 快速指南

Apache CXF - 简介 在当今的环境中&#xff0c;您可以使用多个选项来创建 Web 服务应用程序。您可以使用多种标准和广泛接受的协议中的一种或多种进行通信。例如SOAP、XML/HTTP、RESTful HTTP和CORBA&#xff08;通用对象请求代理架构&#xff0c;在过去非常流行&#xff0c;但…

java cxf 安全_CXF client在并发下的线程安全问题

这个是发生在上周周末的真实案例&#xff0c;因为cxf client 端线程安全导致的错误&#xff0c;总结出来希望其他使用cxf的兄弟注意。 首先描述一下背景&#xff0c;简单的说就是使用cxf作为web service的客户端&#xff0c;运行在weblogic上&#xff0c;连接外部的服务器。为了…

linux cxf服务端,Apache CXF 框架应用实战

一、概述 Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构。它允许创建高性能和可扩展的服务&#xff0c;可以部署在Tomcat和基于Spring的轻量级容器中&#xff0c;也可以部署在更高级的服务器上&#xff0c;例如Jboss、WebSphere或WebLogic。 CXF提供了以下功能…

使用CXF调用WSDL

简介 时隔多年&#xff0c;再次遇到需要调用WebService的业务&#xff0c;对方给予的wsdl说明文档还是内网的链接&#xff0c;并且设有基础访问权限&#xff0c;即在浏览器打开wsdl链接时需要输入【用户名密码】登录后方可查看wsdl文档&#xff0c;这需要设置代理&#xff08;我…

spring5.x cxf3.4.x 服务端和客户端 非maven版本

文章目录 一、资料准备1. 官网链接2. 解压3. 依赖梳理 二、spring集成cxf2.1.创建spring项目2.2. 创建接口2.3. impl2.4. spring-cxf.xml2.5. 客户端2.6. 开源项目 一、资料准备 1. 官网链接 http://cxf.apache.org/download.html 下载apache-cxf-3.4.5.zip 2. 解压 3. 依赖…

CXF实现WebService

一、CXF简介 Apache CXF Celtix XFire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华&#xff0c;提供了对 JAX-WS 全面的支持&#xff0c;并且提供了多种 Binding …

SpringBoot2 整合 CXF 服务端和客户端

文章目录 一、CXF服务端1. 导入依赖2. 创建service接口3. 接口实现类4. cxf配置类5. 查看wsdl结果 二、CXF客户端2.1. 客户端2.2. 断点调试2.3. 发起调用服务开源源码. 一、CXF服务端 1. 导入依赖 <properties><cxf.version>3.3.1</cxf.version></proper…

CXF客户端乱码

CXF客户端乱码 解决办法一&#xff0c;设置服务端代码&#xff1a; 在使用CXF与其他系统对接时&#xff0c;发现对方系统响应的汉字乱码&#xff0c;使用soapui调用测试就没有问题&#xff0c;但是程序里面调用就乱码&#xff0c;很奇怪&#xff0c;乱码如下&#xff1a; 由…

SpringBoot集成CXF

CXF入门篇https://blog.csdn.net/tongxin_tongmeng/article/details/126482362Server端项目结构 Server端pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"…

走进cxf

一、什么是cxf 有很多人认为cxf就是webservice&#xff0c;其实cxf只是发布调用webservice的工具而已 Apache CXF Celtix Xfire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。Apache CXF 是一个开源的 web Service…

NewSQL ---- Mysql.8.0 与 MemSQL 7.0 大数据量查询性能对比

目录 1测试环境以及测试用例设计 1.1测试环境 1.2测试用例设计 2 千万级数据量性能测试对比 2.1 MemSQL时间范围分页查询 2.1.1 性能测试数据 2.2任务信息查询 2.2.1 性能测试数据 2.3 执行批次范围查询 2.3.1 性能测试数据 2.4 批次任务查询 2.4.1 性能测试数据 …