BIO、NIO、AIO详解

一、基础概念: 阻塞/非阻塞、同步/异步

1.1 阻塞/非阻塞和同步/异步这两个概念的区别

1.1.1 他们不是一回事,是两个不同维度

概念 讨论的层面 问题核心
阻塞/非阻塞 线程等待状态 当线程发起I/O操作时,是"停下来等结果",还是"立刻返回自己干别的"
同步/异步 结果通知方式 谁负责通知I/O操作完成?是自己主动去取,还是系统回调告诉你

可以这么理解:

  • "阻塞/非阻塞"->线程等不等
  • "同步/异步"->结果谁来告诉你

两者的本质区别总结一句话: "阻塞/非阻塞"关注的是线程是否空等,"同步/异步"关注的是I/O完成后通知的方式。

1.1.2 一个生活例子: 点外卖 🍔

我们用"点外卖"的例子讲这四种组合:
①同步阻塞(最传统的方式)

你打电话点外卖 → 然后就在家门口等着,直到外卖送到,什么都不干。

  • 线程: 等待中(被阻塞)
  • 结果通知: 靠你自己等
  • 举例: Java的BIO模型
java 复制代码
# 类比
read() // 没数据?我就一直等...

②同步非阻塞

你打电话点外卖 → 然后每隔一会儿跑去门口看看外卖到了没。

  • 线程: 没有被阻塞(可以做别的事)
  • 结果通知: 仍然是你自己反复检查
  • 举例: Java 的 NIO(Selector 轮询)
java 复制代码
# 类比
while(true){
    if(channel.read(buffer) > 0){ 
        // 终于有数据了!
    } else {
        // 没有数据,继续干别的
    }
}

③异步阻塞(理论上存在但不常用)

你打电话点外卖 → 外卖系统说"到了我会打你电话",但你却一直拿着手机等电话(别的事也不做)。

  • 线程: 阻塞(在等通知)
  • 结果通知: 系统(外卖)回调告诉你
    实际系统中不常用

④异步非阻塞(最现代、最高效)

你打电话点外卖 → 系统登记好 → 你继续干别的,外卖送到后系统自动发短信通知你"到了"。

  • 线程: 不阻塞
  • 结果通知: 系统主动回调
  • 举例: Java AIO(异步通道回调 CompletionHandler)
java 复制代码
# 类比
channel.read(buffer, attachment, new CompletionHandler<Integer, Object>() {
    @Override
    public void completed(Integer result, Object attachment) {
        // 有数据可读了!系统通知我来处理
    }
});

二、三种I/O模型概述

2.1 BIO(同步阻塞IO)

BIO(Blocking I/O):指的是当线程执行 I/O 操作时,如果数据没准备好,就会一直等待,直到数据可用或发生异常才返回。

在 Java 网络编程中,BIO 典型表现就是:

一个连接对应一个线程,读写操作会阻塞线程。

2.2 NIO(同步非阻塞IO/多路复用IO)

目的是:让一个线程能同时管理多个连接,实现高并发的网络通信。

与BIO的明显区别是,发起第一次请求后,线程并没有被阻塞,它反复检查数据是否准备好,把原来大块不能用的阻塞时间分成了许多"小阻塞"(检查),所以进程不断有机会被执行。这个检查有没有准备好数据的过程有点类似于"轮询"。
核心组件:

  • Channel:类似传统 I/O 的流,但支持非阻塞操作
  • Buffer:用于数据的读写中转
  • Selector(选择器):核心机制,将多个 Channel 注册到一个 Selector 上,由它监控这些通道的 I/O 事件



IO多路复用

NIO 是上层 API 框架,是 Java 对这种能力的封装;NIO 的 Selector 就是"多路复用器",本质上就是在调用 select / epoll。

  • select: 注册事件由数组管理, 数组是有长度的, 32位机上限1024, 64位机上限2048。轮询查找时需要遍历数组。
  • poll:把select的数组采用链表实现,因此没了最大数量的限制
  • epoll方式:基于事件回调机制,回调时直接通知进程,无须使用某种方式来查看状态。

2.3 AIO(异步非阻塞IO)

核心思想: 应用线程发起 I/O 操作后立即返回,由操作系统在操作完成时自动通知应用(回调)。

也就是说:

线程发起 I/O 请求后不用自己轮询、也不会阻塞,当数据准备好(或者写完)时,系统会调用回调函数 CompletionHandler 来处理结果。

相关推荐
大模型码小白1 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司2 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地3 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
二宝哥4 小时前
CentOS 7.9 系统下 Redis 5.0.4 单机安装与源码编译安装指南
redis·centos
莫逸风6 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
z123456789866 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin5211237 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
做个文艺程序员7 小时前
Linux第24篇:Java应用监控体系搭建:Prometheus+Grafana可视化运维
java·grafana·prometheus
小钻风33668 小时前
Spring Boot 文件上传详解:深入理解 MultipartFile 的使用与原理
java·开发语言
其美杰布-富贵-李8 小时前
Spring Boot 工程开发全流程说明
java·spring boot·后端