IO
IO
79. BIO/NIO/AIO 有什么区别?
回答:
BIO 是传统的同步阻塞 I/O 模型;NIO 是同步非阻塞 I/O;AIO 则是异步非阻塞 I/O。三者在线程使用方式、资源利用效率、底层操作机制等方面均有显著差异。
分析:
Java 的 I/O 模型经历了从 BIO 到 NIO,再到 AIO 的演进过程,核心区别体现在"是否阻塞"和"是否异步"两个维度。
BIO(Blocking IO)
同步阻塞模型,服务器为每一个客户端连接创建一个独立线程处理读写操作,线程在读写时会被阻塞。这种方式实现简单,但当连接数增多时,线程资源消耗巨大,难以支撑高并发。
NIO(Non-blocking IO)
同步非阻塞模型,底层基于多路复用器(Selector),允许一个线程监听多个通道(Channel)。当有事件发生时,才触发相应处理逻辑。线程不再长时间阻塞在某个连接上,提升了资源利用率和并发能力。适用于聊天服务、轻量级任务等场景。
AIO(Asynchronous IO)
异步非阻塞模型,I/O 操作由操作系统完成后异步通知应用程序继续处理。应用程序发起操作后无需等待结果,可立即执行其他逻辑,真正实现 I/O 的"回调式"非阻塞。适用于文件服务器、相册服务等高 I/O 压力场景。
从发展角度看,BIO 是传统模型,适用于小并发应用;NIO 是主流选择,平衡性能与编程复杂度;AIO 适用于高吞吐、长连接场景,但 API 相对复杂,兼容性也存在一定限制。
80. 同步和异步的区别是什么?
回答:
同步是调用方主动等待处理结果,期间阻塞自身逻辑;异步则是调用后立即返回,结果由被调用方通过回调、事件通知等方式后续反馈。
分析:
同步与异步描述的是调用者与被调用者之间的协作模式。
同步调用意味着发起调用后,调用者必须等待操作完成才能继续执行后续逻辑。最典型的例子是普通的 HTTP 请求或数据库查询,必须等返回结果后再处理。
而异步调用在发起请求后立即返回,调用者继续执行自身逻辑,操作完成后通过回调函数、事件监听、状态轮询等方式通知结果。异步编程能够显著提升吞吐量,特别适用于高并发、I/O 密集型任务中。
在 Java 中,Future 和 CompletableFuture 是异步调用的典型支持形式;而线程阻塞调用、同步方法就是同步模型的体现。
总结:同步关注的是调用时机,异步关注的是结果反馈方式。
81. 阻塞和非阻塞的区别?
回答:
阻塞和非阻塞描述的是线程在等待资源(如 I/O)时的状态。阻塞会导致线程挂起,非阻塞则不会等待资源完成立即返回控制权。
分析:
在 I/O 编程中,阻塞与非阻塞直接影响线程调度和系统资源使用效率。
阻塞调用:当线程执行某项操作(如读 socket)时,如果资源尚不可用,线程会挂起直到条件满足,期间不能执行其他任务。例如传统的
InputStream.read(),数据未就绪时线程会被挂起。非阻塞调用:线程在调用某项操作时如果资源不可用,立即返回一个状态(如 0 或 null),线程可以继续执行其他任务。常用于 NIO 模型中,线程通过轮询方式不断检测通道是否可读写。
阻塞模型实现简单但资源浪费严重,适合小并发。非阻塞适合高并发、高吞吐场景,虽然逻辑复杂,但能提升系统整体响应性和资源利用率。
理解阻塞与非阻塞,有助于掌握线程模型优化、I/O 多路复用等核心并发编程技术。