尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
📅 发布时间:2026/7/26 0:15:32

【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

在Java后端开发面试中,IO模型是高频考点。很多同学分不清同步/异步、阻塞/非阻塞,更搞不懂BIO、NIO、AIO的区别。今天我们就用实战代码,从底层原理到具体实现,彻底讲清楚这些概念。## 一、核心概念:同步 vs 异步,阻塞 vs 非阻塞首先,我们要理解两个维度的概念:-同步/异步:关注的是消息通知机制。同步是调用方主动等待结果,异步是被调用方主动通知结果。-阻塞/非阻塞:关注的是调用方在等待结果时的状态。阻塞是调用方被挂起等待,非阻塞是调用方可以继续做其他事。### 1. 同步阻塞(最典型BIO)用户线程发起IO请求后,内核进行数据准备,线程一直阻塞等待,直到数据就绪并拷贝到用户空间。### 2. 同步非阻塞(NIO的基础)用户线程发起IO请求后,立即返回,但需要不断轮询检查数据是否就绪。### 3. 异步阻塞(少见)用户线程发起IO请求后,等待被通知结果,但通知机制是异步的。### 4. 异步非阻塞(AIO)用户线程发起IO请求后,立即返回,当数据就绪时,内核主动通知线程处理。## 二、BIO:同步阻塞IO(Blocking I/O)BIO是最传统的IO模型,每个连接对应一个线程。### 实战代码:BIO服务器javaimport java.io.*;import java.net.*;public class BioServer { public static void main(String[] args) throws IOException { // 创建ServerSocket,监听8080端口 ServerSocket serverSocket = new ServerSocket(8080); System.out.println("BIO Server started on port 8080"); while (true) { // ★ 阻塞点1:accept()会阻塞直到有客户端连接 Socket clientSocket = serverSocket.accept(); System.out.println("Client connected: " + clientSocket.getInetAddress()); // ★ 每个连接创建一个新线程处理 new Thread(() -> { try { // 获取输入输出流 BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter( clientSocket.getOutputStream(), true); String line; // ★ 阻塞点2:readLine()会阻塞直到读取到数据 while ((line = in.readLine()) != null) { System.out.println("Received: " + line); out.println("Echo: " + line); // 回显数据 } } catch (IOException e) { e.printStackTrace(); } finally { try { clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }}BIO的缺点:- 每个连接需要独立线程,连接数多时资源消耗巨大- 线程上下文切换开销大- 适用于连接数少且固定的场景## 三、NIO:同步非阻塞IO(Non-blocking I/O)NIO使用多路复用器(Selector)管理多个通道,一个线程可以处理多个连接。### 实战代码:NIO服务器javaimport java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.util.Iterator;import java.util.Set;public class NioServer { public static void main(String[] args) throws IOException { // 1. 创建Selector(多路复用器) Selector selector = Selector.open(); // 2. 创建ServerSocketChannel并配置为非阻塞 ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); // ★ 关键:设置为非阻塞 serverChannel.bind(new InetSocketAddress(8080)); // 3. 将ServerSocketChannel注册到Selector,关注ACCEPT事件 serverChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("NIO Server started on port 8080"); while (true) { // ★ 阻塞等待就绪的事件(但这是高效的阻塞) int readyChannels = selector.select(); if (readyChannels == 0) continue; // 获取就绪的事件集合 Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { // 处理新连接 ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel clientChannel = server.accept(); clientChannel.configureBlocking(false); // 注册到Selector,关注READ事件 clientChannel.register(selector, SelectionKey.OP_READ); System.out.println("New client connected"); } else if (key.isReadable()) { // 处理可读事件 SocketChannel clientChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead = clientChannel.read(buffer); // ★ 非阻塞读 if (bytesRead > 0) { buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); String message = new String(data); System.out.println("Received: " + message); // 回显数据 ByteBuffer writeBuffer = ByteBuffer.wrap( ("Echo: " + message).getBytes()); clientChannel.write(writeBuffer); // ★ 非阻塞写 } else if (bytesRead == -1) { // 客户端关闭连接 key.cancel(); clientChannel.close(); } } // ★ 重要:移除已处理的key,防止重复处理 keyIterator.remove(); } } }}NIO的核心优势:- 一个线程管理多个连接(通过Selector)- 非阻塞读写,不会阻塞线程- 适用于连接数多、连接时间短的场景(如聊天服务器)## 四、AIO:异步非阻塞IO(Asynchronous I/O)AIO是真正的异步IO,发起IO操作后立即返回,当操作完成时通过回调通知。### 实战代码:AIO服务器(Java 7+)javaimport java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.util.concurrent.ExecutionException;import java.util.concurrent.Future;public class AioServer { public static void main(String[] args) throws IOException, InterruptedException { // 创建异步服务器通道 AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open(); serverChannel.bind(new InetSocketAddress(8080)); System.out.println("AIO Server started on port 8080"); // ★ 异步接受连接,注册CompletionHandler回调 serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void completed(AsynchronousSocketChannel clientChannel, Void attachment) { // 继续接受下一个连接(递归调用) serverChannel.accept(null, this); // 处理客户端连接 ByteBuffer buffer = ByteBuffer.allocate(1024); // ★ 异步读取数据,注册CompletionHandler clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer bytesRead, ByteBuffer attachment) { if (bytesRead > 0) { attachment.flip(); byte[] data = new byte[attachment.limit()]; attachment.get(data); String message = new String(data); System.out.println("Received: " + message); // 异步写回数据 ByteBuffer writeBuffer = ByteBuffer.wrap( ("Echo: " + message).getBytes()); clientChannel.write(writeBuffer, null, new CompletionHandler<Integer, Void>() { @Override public void completed(Integer result, Void attachment) { System.out.println("Write completed"); } @Override public void failed(Throwable exc, Void attachment) { exc.printStackTrace(); } }); } } @Override public void failed(Throwable exc, ByteBuffer attachment) { exc.printStackTrace(); } }); } @Override public void failed(Throwable exc, Void attachment) { exc.printStackTrace(); } }); // 保持主线程运行 Thread.currentThread().join(); }}AIO的特点:- 真正的异步IO,无需轮询- 通过回调机制处理完成事件- 适用于连接数多、连接时间长的场景(如文件服务器)- 但实际应用中NIO更常用(操作系统支持更好)## 五、总结对比| 模型 | 同步/异步 | 阻塞/非阻塞 | 线程模型 | 适用场景 ||------|-----------|-------------|----------|----------|| BIO | 同步 | 阻塞 | 一个连接一个线程 | 连接数少、固定 || NIO | 同步 | 非阻塞 | 一个线程管理多连接 | 连接数多、短连接 || AIO | 异步 | 非阻塞 | 回调机制 | 连接数多、长连接 |面试重点:1. BIO的accept()和read()是阻塞点,NIO通过Selector实现多路复用2. NIO虽然是非阻塞,但仍然是同步IO(需要主动轮询/处理事件)3. AIO才是真正的异步IO,但实际项目中NIO更常用(如Netty基于NIO)4. 理解IO模型对设计高性能服务器至关重要实战建议:- 简单应用用BIO(如小型内网工具)- 高并发网络应用首选NIO(如Netty框架)- 文件操作可以考虑AIO(如大文件读写)希望这篇文章能帮你彻底理解IO模型,面试不再怕!

相关新闻

  • Anaconda-mode未来路线图:新功能预测与社区贡献指南
  • UE5开发效率秘籍:控制台指令与上帝模式实战指南
  • OpenCV工程师招聘:计算机视觉项目开发需求

最新新闻

  • 2026宁波工厂采购工业强力风扇的线下走访记录 - 起跑123
  • 2026年江浙沪区域吸塑泡壳厂商哪家强实用选型参考指南 - 热点品牌推荐
  • 2026年云南昆明专业分包实际施工人靠谱律师咨询指南 - 装修教育财税推荐2026
  • 2026试水服装直播团购 分享广州机构挑选的真实体验 - 起跑123
  • Django毕设项目: 协同过滤算法在音乐推荐系统中的应用与实现 个性化收藏音乐智能推送系统设计(源码+文档,讲解、调试运行,定制等)
  • 2026年7月最新南方避暑温泉热门景区点位综合排行一览 - 起跑123

日新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号