BIO、NIO、AIO到底有什么区别?从“一个连接一个线程”到“百万级并发”,彻底搞懂 Java IO 模型! BIO、NIO、AIO到底有什么区别从“一个连接一个线程”到“百万级并发”彻底搞懂 Java IO 模型很多 Java 后端开发者面试时都会被问BIO、NIO、AIO 有什么区别很多人的回答“BIO 是阻塞NIO 是非阻塞AIO 是异步。”这句话没错但是面试官继续追问为什么 BIO 不能支撑高并发NIO 为什么一个线程能处理多个连接Selector 到底做了什么AIO 为什么实际项目用得少很多人就答不上来了。今天通过一篇文章彻底搞懂 Java IO 模型演进BIO ↓ NIO ↓ AIO以及它们背后的高并发设计思想。一、什么是 IOIO全称Input / Output输入 / 输出简单理解程序和外部设备进行数据交换的过程就是 IO。例如读取文件文件 ↓ 程序网络通信客户端 ↓ 服务器都属于 IO。二、什么是网络 IO网络 IO程序通过网络进行数据发送和接收的过程。例如用户访问网站浏览器 发送请求 ↓ 服务器 返回数据 ↓ 浏览器其中接收数据 Input发送数据 OutputJava 中网络 IO 主要经历BIO ↓ NIO ↓ AIO三、BIO一个连接一个线程的时代1. BIO 是什么BIO全称Blocking IO同步阻塞 IO核心特点一个客户端连接对应一个线程。结构客户端1 | ↓ 线程1 客户端2 | ↓ 线程2 客户端3 | ↓ 线程32. BIO 如何工作服务器ServerSocketserverSocketnewServerSocket(8080);while(true){SocketsocketserverSocket.accept();}关键accept()如果没有客户端连接线程等待。读取数据inputStream.read();如果客户端没有发送数据线程继续等待。所以BIO 最大的问题线程大量阻塞等待 IO。四、BIO 为什么不能支撑高并发假设10000 个用户连接服务器。BIO10000个连接 ↓ 10000个线程问题1. 线程资源消耗大一个线程需要栈空间内存JVM资源2. CPU上下文切换严重CPU 不断切换线程1 线程2 线程3 ... 线程10000大量时间浪费在线程切换。所以BIO适合小规模连接简单应用不适合高并发服务器五、NIO一个线程管理多个连接1. NIO 是什么NIO全称Non-blocking IO同步非阻塞 IO核心思想不要让线程等待某一个连接而是让一个线程管理多个连接。结构客户端1 | 客户端2 | 客户端N ---- Selector ---- 一个线程 | 客户端3六、NIO 三大核心组件1. Channel通道Channel类似 BIO 的 Socket。作用负责网络连接和数据传输。例如SocketChannel表示一个 TCP 连接。2. Buffer缓冲区NIO 不直接操作数据。数据经过 Buffer网络 ↓ Channel ↓ Buffer ↓ 程序例如ByteBufferbuffer;作用暂存数据。3. Selector选择器⭐Selector 是 NIO 高并发核心。它可以监听多个 Channel例如连接1 有数据吗 连接2 有数据吗 连接3 有数据吗 连接10000 有数据吗当连接2准备好了。Selector通知连接2可以处理。这叫IO 多路复用一句话一个线程同时监听多个 IO 连接。七、NIO 工作流程完整流程创建Channel ↓ 注册Selector ↓ Selector监听事件 ↓ 发现可读/可写事件 ↓ 处理数据例如监听selector.select();作用等待连接事件读事件写事件八、NIO 为什么性能更高核心区别BIO线程等待线程1 等待客户端1数据 线程2 等待客户端2数据大量线程空闲。NIO线程等待一个线程 ↓ Selector ↓ 监听10000个连接只有真正有数据的连接才处理。所以NIO 节省的是大量等待 IO 的线程资源。九、AIO真正异步 IO1. AIO 是什么AIO全称Asynchronous IO异步 IO核心思想程序发起 IO 请求后不用等待操作系统完成后主动通知程序。流程程序 提交IO请求 ↓ 继续执行其他任务 ↓ 操作系统完成IO ↓ 通知程序 ↓ 处理结果十、用生活例子理解三者假设去餐厅吃饭。BIO点餐后你一直站在窗口等特点同步阻塞。NIO点餐后拿号码牌 自己关注有没有叫号特点同步非阻塞。AIO点餐后留下联系方式 餐好了服务员通知你特点异步非阻塞。十一、BIO、NIO、AIO 对比BIONIOAIO全称Blocking IONon-blocking IOAsynchronous IO中文同步阻塞IO同步非阻塞IO异步非阻塞IO线程模型一个连接一个线程一个线程管理多个连接系统完成后通知是否阻塞阻塞非阻塞非阻塞数据获取方式主动等待主动查询被动通知并发能力低高高实现难度简单较复杂复杂十二、Java 中实际使用情况BIO现在较少使用。例如ServerSocketSocketNIO目前最主流。典型NettyNetty ↓ Java NIO ↓ Selector应用DubboRocketMQgRPCAIOJava 提供AsynchronousSocketChannel但是实际互联网开发中较少。原因1. 操作系统支持差异不同系统实现不同。2. NIO Netty 已经足够优秀所以工程中更多选择NIO Netty十三、面试最终回答如果面试官问BIO、NIO、AIO 有什么区别可以回答BIO 是同步阻塞 IO一个连接对应一个线程简单但并发能力有限NIO 是同步非阻塞 IO通过 Channel、Buffer 和 Selector 实现 IO 多路复用一个线程可以管理多个连接提高并发能力AIO 是异步非阻塞 IO由操作系统完成 IO 后主动通知应用程序。实际 Java 后端开发中NIONetty 是目前最常见的高性能网络通信方案。最后一句话记忆BIO 一个连接一个线程。 NIO 一个线程管理多个连接。 AIO 不用等完成后通知我。真正理解这三个模型你就掌握了 Java 高并发网络编程的核心思想。