阻塞非阻塞IO(BIO和NIO),IO多路复用
1.概念
NIO(New Input/Output)和BIO(Blocking Input/Output)是Java中用于处理输入输出的两种不同的模型。

BIO 会阻塞,等有了消息,立刻返回,一个线程处理一个recv(需要很多线程)。
NIO 有没有消息,都返回(但程序要自己判断,返回空就循环重复);一个线程可以处理多个recv(好处:不用很多线程;坏处:线程空转,cpu浪费严重)。

Java中新的NIO包可以通过上述形式设置是否开启阻塞,从而设置NIO或BIO,两者都支持;
IO多路复用
IO多路复用(IO Multiplexing)是一种通过单线程处理多个I/O操作的机制。它允许一个进程同时监听多个文件描述符(如Socket),并在有数据可读或可写时进行相应的处理,从而提高系统的并发性能。
在传统的阻塞I/O模型中,每个I/O操作都需要一个独立的线程来处理,当并发量增加时,线程数量会急剧增加,导致系统资源消耗过大。而使用IO多路复用,只需要一个线程就可以同时处理多个I/O操作,大大减少了线程的数量和系统开销。
常见的IO多路复用机制包括:
-
select:select是Unix系统最早引入的IO多路复用机制。它通过select函数来监听多个文件描述符,当其中任意一个文件描述符准备就绪时,select函数会返回,然后可以通过遍历文件描述符集合来确定哪些文件描述符可读或可写。
-
poll:poll是select的一种改进版本。它使用一个pollfd结构体数组来管理文件描述符,并通过poll函数来监听多个文件描述符的状态。与select相比,poll没有最大文件描述符数量的限制。
-
epoll:epoll是Linux系统引入的一种高效的IO多路复用机制。它使用一个事件表来管理文件描述符,并通过epoll_ctl函数来注册和删除事件,通过epoll_wait函数来等待事件的发生。epoll提供了三种工作模式:边沿触发(EPOLLET)、水平触发(EPOLLIN、EPOLLOUT)和一次性触发(EPOLLONESHOT),可以根据具体需求选择适合的模式。(epoll可以理解为多了个记事本,)
IO多路复用适用于处理大量的并发连接,如服务器端的网络编程。它可以有效地减少线程的数量,提高系统的并发性能和资源利用率。
可以说:
select内核无状态,每次从零开始
eqoll内核维护一个状态,可以异步做很多事情,调用的时候能够立刻给出结果集
额外拓展
1.epoll机制详解
epoll是Linux系统引入的一种高效的IO多路复用机制,它提供了一种事件驱动的方式来处理多个文件描述符的I/O操作。相比于传统的select和poll机制,epoll在处理大量并发连接时具有更高的性能。
epoll的核心概念包括以下几个部分:
-
epoll实例(epoll instance):epoll实例是一个内核数据结构,用于管理文件描述符和事件。通过epoll_create函数来创建一个epoll实例。
-
文件描述符(file descriptor):文件描述符是操作系统对文件或I/O设备的引用。在epoll中,需要将需要监听的文件描述符添加到epoll实例中。
-
事件(event):事件是对文件描述符的一种状态变化的表示,如可读、可写等。在epoll中,通过epoll_event结构体来表示事件。
-
事件表(event table):事件表是epoll实例中用来存储事件的数据结构,可以通过epoll_ctl函数来注册和删除事件。
epoll的工作流程如下:
-
创建epoll实例:通过epoll_create函数创建一个epoll实例,并返回一个文件描述符,用于后续的操作。
-
添加文件描述符:通过epoll_ctl函数将需要监听的文件描述符添加到epoll实例中,并指定需要监听的事件类型。
-
等待事件:通过epoll_wait函数等待事件的发生。当有文件描述符的事件发生时,epoll_wait函数会返回,并将事件信息填充到一个epoll_event数组中。
-
处理事件:遍历epoll_event数组,根据事件类型进行相应的处理。
-
循环操作:重复执行等待事件和处理事件的过程,实现持续的事件驱动。
epoll提供了三种工作模式:
-
边沿触发(EPOLLET):只有在文件描述符状态发生变化时才触发事件,适用于高效处理大量的并发连接。
-
水平触发(EPOLLIN、EPOLLOUT):只要文件描述符处于可读或可写状态,就会触发事件,适用于普通的网络编程。
-
一次性触发(EPOLLONESHOT):只触发一次事件,需要在处理完事件后重新注册。
epoll的优势在于可以处理大量的并发连接,具有更高的性能和资源利用率。它避免了传统select和poll机制中遍历文件描述符集合的开销,同时提供了更灵活的事件触发方式。因此,epoll被广泛应用于高性能的网络服务器编程。
2.BIO什么时候会阻塞?
BIO(Blocking I/O,阻塞I/O)是一种同步的I/O模型,在进行I/O操作时会阻塞当前线程,直到操作完成或出现错误。以下情况下,BIO会发生阻塞:
-
读取阻塞:当从输入流(如Socket的InputStream)读取数据时,如果没有可读取的数据,读取操作将会阻塞,直到有数据可读或者发生超时或错误。
-
写入阻塞:当向输出流(如Socket的OutputStream)写入数据时,如果输出缓冲区已满,写入操作将会阻塞,直到有空间可写或者发生超时或错误。
-
连接阻塞:在使用ServerSocket等待客户端连接时,accept()方法会阻塞当前线程,直到有客户端连接成功或发生超时或错误。
BIO的阻塞特性意味着在进行I/O操作时,线程会一直等待,不能处理其他任务。这可能导致资源浪费和性能下降。因此,对于高并发的网络应用,通常使用NIO(Non-blocking I/O,非阻塞I/O)或AIO(Asynchronous I/O,异步I/O)模型来避免阻塞。
3.上文提到的缓冲区(详解)
概念和作用:缓冲区(Buffer)是在进行I/O操作时用于临时存储数据的一块内存区域。它提供了一种缓冲数据的机制,可以减少实际的I/O操作次数,提高数据读写的效率。
在Java中,缓冲区是通过Buffer类的实例来表示的。Java NIO(New I/O)库提供了一组缓冲区类,如ByteBuffer、CharBuffer、ShortBuffer等,用于处理不同类型的数据。
缓冲区有以下几个重要的属性:
-
容量(Capacity):缓冲区的容量表示它可以存储的最大数据量。一旦创建,缓冲区的容量就是固定的,不能改变。
-
位置(Position):缓冲区的位置表示当前读写操作的位置。初始时,位置为0,随着读写操作进行,位置会自动更新。
-
上界(Limit):缓冲区的上界表示有效数据的末尾位置。读写操作不能超过上界。
-
标记(Mark):缓冲区的标记是一个备忘位置,可以通过mark()方法设置,并通过reset()方法恢复到标记位置。
缓冲区的基本操作包括:
-
写入数据:通过put()方法将数据写入缓冲区,同时位置会自动向后移动。
-
读取数据:通过get()方法从缓冲区读取数据,同时位置会自动向后移动。
-
翻转缓冲区:通过flip()方法将上界设置为当前位置,位置重置为0,用于将缓冲区从写模式切换到读模式。
-
清空缓冲区:通过clear()方法将位置设置为0,上界设置为容量,用于将缓冲区从读模式切换到写模式。
缓冲区的使用可以提高I/O操作的效率,特别是在处理大量数据时。它可以减少系统的调用次数,提高数据读写的速度。
相关文章:
阻塞非阻塞IO(BIO和NIO),IO多路复用
1.概念 NIO(New Input/Output)和BIO(Blocking Input/Output)是Java中用于处理输入输出的两种不同的模型。 BIO 会阻塞,等有了消息,立刻返回,一个线程处理一个recv(需要很多线程&…...
HTTP协议初识·中篇
加上目录,会出现导向不正确的情况,可能是bug,目录一长就容易出错? 本篇主要讲解了: 网页分离(网页代码和.c文件分离) html链接跳转 网页添加图片 确认并返回资源类型 填写正文长度属性 添加表单 临时重定向 补充知识&a…...
数学建模:拟合算法
🔆 文章首发于我的个人博客:欢迎大佬们来逛逛 数学建模:拟合算法 文章目录 数学建模:拟合算法拟合算法多项式拟合非线性拟合cftool工具箱的使用 拟合算法 根据1到12点间的温度数据求出温度与时间之间的近似函数关系 F ( t ) F(…...
计算机网络-笔记-汇总
目录 📚 前言 🌸章节汇总 🚀 学习心得 ⌛2023年8月31日 星期四 📚 前言 在学习了【操作系统】、【计算机组成原理】之后 再来学习【计算机网络】,对计算机之间如何通信,有了一个大致的认识。 可以想象…...
STM32定时器定时及其应用
STM32定时器定时及其应用 定时器概述☆定时器相关配置CubeMX工程配置及程序实现固件库程序设计及实现 定时器概述 1. 工作原理 使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器 2. 定时器分类 基本定时器(TIM6~TIM7…...
(牛客) 游游的字符重排(next_permutation的使用)
题目描述 游游定义一个字符串是“好串”,当且仅当该字符串相邻的字符不相等。例如"arcaea"是好串,而"food"不是好串。 游游拿到了一个字符串,她可以将该字符串的各个字符顺序随意打乱。她想知道一共可以生产多少种不同的…...
RTPEngine 通过 HTTP 获取指标的方式
文章目录 1.背景介绍2.RTPEngine 支持的 HTTP 请求3.通过 HTTP 请求获取指标的方法3.1 脚本配置3.2 请求方式 1.背景介绍 RTPEngine 是常用的媒体代理服务器,通常被集成到 SIP 代理服务器中以减小代理服务器媒体传输的压力,其架构如下图所示。这种使用方…...
聚鑫数藏平台——引领数字资产管理新风向
随着数字经济的飞速发展,新金融生态应运而生。区块链技术的崭新突破,使数字资产的重要性日益凸显,为投资者带来了前所未有的机遇和挑战。在此背景下,聚鑫数藏平台横空出世,引领着数字资产管理的新风向。 聚鑫数藏平台&…...
web3j solidity 转java
需要使用的环境 web3j,nodejs 安装编译sol工具 1 $ npm install -g solc 保存为hello.sol文件到本地 1 2 3 4 5 6 7 8 pragma solidity 0.4.19; contract hello { function main(uint a) constant returns (uint b) { uint result a * 8; …...
uniapp项目实战系列(3):底部导航栏与头部导航栏的配置
目录 系列往期文章(点击跳转)uniapp项目实战系列(1):导入数据库,启动后端服务,开启代码托管(点击跳转)uniapp项目实战系列(2):新建项目,项目搭建,微信开发工具…...
Jwt工具类
导入依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifactId>jax…...
计算机网络-笔记-第五章-运输层
🌸章节汇总 一、第一章——计算机网络概述 二、第二章——物理层 三、第三章——数据链路层 四、第四章——网络层 五、第五章——运输层 六、第六章——应用层 目录 五、第五章——运输层 1、运输层概述 2、运输层端口号、复用、分用 (1࿰…...
java-参数传递机制
java参数传递机制都是值传递。 基本类型参数传输都是数据值。 传递到方法中的值是拷贝后的值。 引用类型参数传输的都是地址值。 如果是数组的参数传递,那么是引用传递(本质上还是值传递,但是由于数组的值传递是传递数组的内存地址…...
Python编程练习与解答 练习96:字符串是否表示整数
本练习将编写一个名为isInteger的函数,用于确定字符串中的字符是否代表有效整数,确定字符串是否表示整数时,则应忽略开通要或者结尾的任何空白。一旦这个空白被忽略,如果字符串的长度至少是1,且只包含数字,…...
Scala的特质trait与java的interface接口的区别,以及Scala特质的自身类型和依赖注入
1. Scala的特质trait与java接口的区别 Scala中的特质(trait)和Java中的接口(interface)在概念和使用上有一些区别: 默认实现:在Java中,接口只能定义方法的签名,而没有默认实现。而在…...
检查js中的字符串是否可以成为回文
探索 JavaScript 中的字符串操作领域揭示了一个令人着迷的挑战:确定给定的字符串是否可以转换为回文。回文,即正反读相同的单词或短语,具有固有的吸引力,并激发了寻求揭开其神秘属性的开发人员的好奇心。在本文中,我们…...
时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测(风电功率预测)
时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测(风电功率预测) 目录 时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测(风电功率预测)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1…...
WebSocket--技术文档--基本概念--《快速了解WebSocket协议》
阿丹: 不断学习新技术,丰富自己了解更多才能扩展更多世界可能。 官网 WebSocket首页、文档和下载 - HTML5开发相关 - OSCHINA - 中文开源技术交流社区 软件简介 WebSocket 是 HTML5 开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 WebS…...
flutter报错-cmdline-tools component is missing
安装完androidsdk和android studio后,打开控制台,出现错误 解决办法 找到自己安装android sdk的位置,然后安装上,并将下面的勾选上 再次运行 flutter doctor 不报错,出现以下画面 Doctor summary (to see all det…...
torch.bmm功能解读
bmm 是 batched matrix multiple 的简写,即批量矩阵乘法,矩阵是二维的,加上batch一个维度,因此该函数的输入必须是两个三维的 tensor,三个维度代表的含义分别是:(批量,行,…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
