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

【java】BIO,NIO,多路IO复用,AIO

在Java中,处理I/O操作的模型主要有四种:阻塞I/O (BIO), 非阻塞I/O (NIO), 异步I/O (AIO), 以及IO多路复用。下面详细介绍这四种I/O模型的工作原理和应用场景。

1. 阻塞I/O (BIO)

工作原理

阻塞I/O是最传统的I/O模型。在这种模型中,当一个线程发起一个I/O请求(如读写操作)时,该线程会被阻塞,直到I/O操作完成。这意味着线程必须等待I/O操作完成才能继续执行。

代码示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class BioServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("Server started on port 8080");while (true) {Socket clientSocket = serverSocket.accept(); // 阻塞等待客户端连接new Thread(() -> {try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {String line;while ((line = reader.readLine()) != null) {System.out.println("Received: " + line);}} catch (IOException e) {e.printStackTrace();}}).start();}}
}
优点
  • 实现简单。
缺点
  • 每个连接都需要一个线程来处理,当并发连接数增加时,线程的数量也会增加,可能导致系统资源耗尽。

2. 非阻塞I/O (NIO)

工作原理

非阻塞I/O模型允许线程在发起I/O请求时不会被阻塞,如果数据不可用或设备忙,则立即返回一个错误或特殊值。线程可以选择立即再次尝试I/O操作或去做其他事情,从而提高了CPU的利用率。

代码示例
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class NioServer {public static void main(String[] args) throws IOException {Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();if (key.isAcceptable()) {ServerSocketChannel ssc = (ServerSocketChannel) key.channel();SocketChannel sc = ssc.accept();sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel sc = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int readBytes = sc.read(buffer);if (readBytes > 0) {buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);System.out.println("Received: " + new String(data));}}keyIterator.remove();}}}
}
优点
  • 提高了单个线程处理多个连接的能力,降低了系统资源消耗。
  • 可以处理大量并发连接。
缺点
  • 实现相对复杂。
  • 需要手动管理缓冲区、选择器等。

3. IO多路复用

工作原理

IO多路复用允许一个进程同时监听多个文件描述符(例如socket),并只在某个描述符准备好进行读写操作时才进行处理。常用的多路复用机制有selectpollepoll。这种模型非常适合处理大量并发连接的场景。

代码示例
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;public class SelectServer {public static void main(String[] args) throws IOException {Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();for (SelectionKey key : selector.selectedKeys()) {if (key.isAcceptable()) {ServerSocketChannel ssc = (ServerSocketChannel) key.channel();SocketChannel sc = ssc.accept();sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel sc = (SocketChannel) key.channel();// 读取数据...}}selector.selectedKeys().clear();}}
}
优点
  • 可以同时监听多个文件描述符,提高处理大量并发连接的能力。
  • 提高了资源利用率。
缺点
  • 在Java中,selectpoll的性能不如epoll,后者仅在Linux系统中可用。

4. 异步I/O (AIO)

工作原理

异步I/O是真正的异步操作模型,进程发起I/O请求后可以立即返回并继续执行其他任务,而无需等待I/O操作完成。当I/O操作完成后,操作系统会通知进程结果。

代码示例
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;public class AioServer {private static final CountDownLatch latch = new CountDownLatch(1);public static void main(String[] args) throws IOException, InterruptedException {AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open().bind(new java.net.InetSocketAddress(8080));server.accept(null, new AcceptHandler(server));latch.await();}static class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {private AsynchronousServerSocketChannel server;public AcceptHandler(AsynchronousServerSocketChannel server) {this.server = server;}@Overridepublic void completed(AsynchronousSocketChannel result, Object attachment) {result.read(ByteBuffer.allocate(1024), null, new ReadHandler(result));server.accept(null, this);}@Overridepublic void failed(Throwable exc, Object attachment) {exc.printStackTrace();latch.countDown();}}static class ReadHandler implements CompletionHandler<Integer, Object> {private AsynchronousSocketChannel channel;public ReadHandler(AsynchronousSocketChannel channel) {this.channel = channel;}@Overridepublic void completed(Integer result, Object attachment) {ByteBuffer buffer = (ByteBuffer) attachment;buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);System.out.println("Received: " + new String(data));channel.close();}@Overridepublic void failed(Throwable exc, Object attachment) {exc.printStackTrace();try {((AsynchronousSocketChannel) attachment).close();} catch (IOException e) {e.printStackTrace();}}}
}
优点
  • 真正的异步操作,提高了系统的并发能力和响应速度。
  • 适用于高并发场景。
缺点
  • 实现较为复杂。
  • Java中AIO的支持相对较少,不如NIO成熟。

总结

  • BIO:适合连接数较少的场景。
  • NIO:适用于中等并发的场景,提高了资源利用率。
  • IO多路复用:适合大量并发连接的场景,特别是在服务器端。
  • AIO:适用于高并发场景,真正实现了异步操作。

选择哪种模型取决于具体的应用场景和需求。例如,对于需要处理大量并发连接的服务器,IO多路复用和异步I/O可能是更佳的选择。而对于简单的、单线程的应用,阻塞I/O可能就已经足够。

相关文章:

【java】BIO,NIO,多路IO复用,AIO

在Java中&#xff0c;处理I/O操作的模型主要有四种&#xff1a;阻塞I/O (BIO), 非阻塞I/O (NIO), 异步I/O (AIO), 以及IO多路复用。下面详细介绍这四种I/O模型的工作原理和应用场景。 1. 阻塞I/O (BIO) 工作原理 阻塞I/O是最传统的I/O模型。在这种模型中&#xff0c;当一个线…...

服务器怎样减少带宽消耗的问题?

择业在使用服务器的过程中会消耗大量的带宽资源&#xff0c;而减少服务器的带宽消耗则可以帮助企业降低经济成本&#xff0c;同时还能够提高用户的访问速度&#xff0c;那么服务器怎样能减少带宽的消耗呢&#xff1f;本文就来带领大家一起来探讨一下吧&#xff01; 企业可以选择…...

linux 报错:bash: /etc/profile: 行 32: 语法错误:未预期的文件结束符

目录 注意错误不一定错在最后一行 i进入编辑 esc退出编辑 &#xff1a;wq 保存编辑退出 &#xff1a;q&#xff01;不保存退出 if [ $# -eq 3 ] then if [ ! -e "$1" ]; then miss1 $1 elif [ ! -e "$2" -a ! -e "$3" ]; then miss2and3…...

MySQL练习(5)

作业要求&#xff1a; 实现过程&#xff1a; 一、触发器 &#xff08;1&#xff09;建立两个表&#xff1a;goods&#xff08;商品表&#xff09;、orders&#xff08;订单表&#xff09; &#xff08;2&#xff09;在商品表中导入商品记录 &#xff08;3&#xff09;建立触发…...

泛型新理解

1.创建三个类&#xff0c;并写好对应关系 package com.jmj.gulimall.study;public class People { }package com.jmj.gulimall.study;public class Student extends People{ }package com.jmj.gulimall.study;public class Teacher extends People{ }2.解释一下这三个方法 pub…...

JavaSE--基础语法--继承和多态(第三期)

一.继承 1.1我们为什么需要继承? 首先&#xff0c;Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是 现实世界错综复杂&#xff0c;事物之间可能会存在一些关联&#xff0c;那在设计程…...

高级java每日一道面试题-2024年7月23日-什么时候用包装类, 什么时候用原始类

面试官: 你在什么时候用包装类, 什么时候用原始类? 我回答: 在Java开发中&#xff0c;理解何时使用包装类&#xff08;Wrapper Classes&#xff09;和何时使用原始类&#xff08;Primitive Types&#xff09;是非常重要的。这主要取决于你的具体需求以及Java语言本身的一些限…...

LINUX之MMC子系统分析

目录 1. 概念1.1 MMC卡1.2 SD卡1.3 SDIO 2. 总线协议2.1 协议2.2 一般协议2.3 写数据2.4 读数据2.5 卡模式2.5.1 SD卡模式2.5.2 eMMC模式 2.6 命令2.6.1 命令类2.6.2 详细命令 2.7 应答2.8 寄存器2.8.1 OCR2.8.2 CID2.8.3 CSD2.8.4 RCA2.8.5 扩展CSD 3. 关键结构3.1 struct sdh…...

VulnHub:cengbox1

靶机下载地址&#xff0c;下载完成后&#xff0c;用VirtualBox打开靶机并修改网络为桥接即可搭建成功。 信息收集 主机发现和端口扫描 扫描攻击机&#xff08;192.168.31.218&#xff09;同网段存活主机确认目标机ip&#xff0c;并对目标机进行全面扫描。 nmap 192.168.31.…...

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅&#xff0c;继续上篇的DDL、DML、DQL、以及一些约束&#xff0c;该到了多表查询和事务的学习总结&#xff0c;以及相关的案例实现&#xff0c;为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…...

Java的序列化和反序列化

序列化&#xff1a; 将数据结构或对象转换成二进制串的过程 反序列化&#xff1a;将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程 至于为什么要序列化和反序列化呢&#xff1f; 因为互联网的产生带来了机器间通讯的需求&#xff0c;而互联通讯的双方需要采用约…...

本地连接远程阿里云K8S

1.首先安装kubectl 1.1验证自己系统 uname -m 1.2 按照步骤安装 在 Linux 系统中安装并设置 kubectl | Kubernetes 1.3 阿里云配置 通过kubectl连接Kubernetes集群_容器服务 Kubernetes 版 ACK(ACK)-阿里云帮助中心 2.验证 阿里云config直接导出&#xff0c;直接扔到.…...

CasaOS设备使用Docker安装SyncThing文件同步神器并实现远程管理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

k210 图像操作详解(一)(直线检测、边缘检测、色块追踪)

1、直线检测 ##################################################################################################### # file main.py # author 正点原子团队(ALIENTEK) # version V1.0 # date 2024-01-17 # brief image图像特征检测实…...

【Java版数据结构】初识泛型

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;Java版数据结构 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…...

DevExpress WinForms自动表单布局,创建高度可定制用户体验(二)

使用DevExpress WinForms的表单布局组件可以创建高度可定制的应用程序用户体验&#xff0c;从自动安排UI控件到按比例调整大小&#xff0c;DevExpress布局和数据布局控件都可以让您消除与基于像素表单设计相关的麻烦。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&a…...

vue中v-if和v-for

vue中v-if和v-for Vue 官方建议不要在同一个元素上同时使用 v-if 和 v-for 指令&#xff0c;主要有以下几个原因&#xff1a; 性能问题&#xff1a; 当 v-if 和 v-for 一起使用时&#xff0c;Vue 在每次渲染时都需要先执行循环&#xff0c;然后再对每个元素进行条件判断。这可能…...

【MySQL】根据binlog日志获取回滚sql的一个开发思路

根据binlog日志获取回滚sql的一个开发思路 需要获取的信息 thread_id 打开 mysql 客户端 开始时间 关闭 mysql 客户端 结束时间 binlog 匹配流程 指定 mysql 客户端 开始时间和结束时间 先匹配 thread_id 相同的 然后匹配 ^BEGIN$行和 ^COMMIT/*!*/;$行之间的数据 当匹…...

Kafka快速入门+SpringBoot简单的秒杀案例

1. 主题相关 1.1 创建主题 kafka-topics.sh --create --bootstrap-server [服务器地址] --replication-factor [副本数] --partitions [分区数] --topic [主题名]liberliber-VMware-Virtual-Platform:/home/zookeeper$ docker-compose exec kafka /bin/bash #进入kafka容器 b…...

Redis哨兵机制

哨兵机制&#xff1a; &#xff08;1&#xff09;监控&#xff1a;有一个哨兵集群&#xff0c;这个哨兵集群检测redis的主从集群。它是每隔1秒钟就向主从集群中的节点发送心跳&#xff0c;如果节点没有回复&#xff0c;则这个哨兵就主观的认为这个节点发生故障&#xff0c;这时…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...