NIO(二)—— 什么是阻塞?什么是非阻塞?

本文详细解释了阻塞与非阻塞的概念,通过实例对比了两者在请求操作条件不满足时的行为差异,并深入探讨了同步与异步与阻塞与非阻塞之间的关系。同时,文章提供了理解这两组概念的关键信息,为后续的IO模型学习打下坚实的基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       阻塞:当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足;

   非阻塞:当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待。

   这就是阻塞和非阻塞的区别。也就是说阻塞和非阻塞的区别关键在于当发出请求一个操作时,如果条件不满足,是会一直等待还是返回一个标志信息。

   举个简单的例子:假如我要读取一个文件中的内容,如果此时文件中没有内容可读,对于阻塞来说就是会一直在那等待,直至文件中有内容可读;而对于非阻塞来说,就会直接返回一个标志信息告知文件中暂时无内容可读。

  

       在网上有一些朋友将同步和异步分别与阻塞和非阻塞画上等号,事实上,它们是两组完全不同的概念。注意,理解这两组概念的区别对于后面IO模型的理解非常重要。

   同步和异步着重点在于多个任务的执行过程中,一个任务的执行是否会导致整个流程的暂时等待;

   而阻塞和非阻塞着重点在于发出一个请求操作时,如果进行操作的条件不满足是否会返会一个标志信息告知条件不满足。

  

 

 

### Java I/O模型对比 #### BIO(同步阻塞I/O) BIO是一种基于传统流的方式进行读写操作的模式。在这种模式下,服务器端为每一个客户端请求创建一个新的线程来处理该请求,并且在这个过程中会一直等待直到完成整个过程中的所有交互[^1]。这种方式适合于连接数目有限的应用程序环境之中;当面对大量并发访问时,则可能因线程数量激增而引发性能瓶颈。 对于简单的应用场景以及低负载的服务来说,采用BIO可以简化开发难度并保持良好的可维护性。但是随着业务规模的增长和技术需求的变化,特别是互联网应用向大规模分布式架构演进的趋势日益明显,单纯依靠增加硬件资源已经难以满足高效能的要求,此时就需要考虑其他更为先进的技术方案了[^3]。 #### NIO(非阻塞I/O) NIO是在JDK 1.4版本之后被引入的新一代输入输出框架,其核心在于支持非阻塞式的通信方式及多路复用的选择器机制。这使得单个线程能够同时监控多个通道的状态变化情况,从而大大减少了系统开销和提高了响应速度。具体而言: - **缓冲区(Buffer)**:用于存储临时的数据片段; - **通道(Channel)** :负责实际的数据传输动作; - **选择器(Selector)** :允许一个单独的线程去监听多个注册过的Channel对象上的事件通知。 相比于之前的BIO方法论,虽然增加了编程复杂度但却带来了显著的优势——特别是在应对海量级联接方面表现尤为突出[^2]。 #### AIO(异步非阻塞I/O) AIO自JDK7起得到官方的支持,代表了一种更加高级别的抽象层次。不同于前两者需要显式地调用read/write函数来进行数据交换活动,在这里所有的操作都是由操作系统底层自动完成后再回调给上层应用程序告知结果状态。这意味着开发者无需关心具体的执行细节就能享受到高效的吞吐量和服务质量保障。 总结来看,三种不同类型的Java IO模型各有千秋,选择哪一种取决于特定项目的需求分析与权衡考量。如果追求极致的速度体验并且愿意承担额外的学习成本的话,那么显然应该优先尝试后者;反之则可根据实际情况灵活选用前者之一作为解决方案[^4]。 ```java // 示例代码展示如何使用NIO Selector监听多个Socket Channel import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; public class NioServerExample { public static void main(String[] args) throws IOException { // 创建Selector实例 Selector selector = Selector.open(); // 打开服务端套接字通道 ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.socket().bind(new InetSocketAddress(8080)); serverChannel.configureBlocking(false); // 注册到selector, 并指定关注OP_ACCEPT事件 SelectionKey key = serverChannel.register(selector, SelectionKey.OP_ACCEPT); while (true){ int readyChannels = selector.select(); if(readyChannels == 0) continue; for (SelectionKey sk : selector.selectedKeys()){ if(sk.isAcceptable()) { /* 处理新的连接 */ } else if(sk.isReadable()){ /* 处理读取就绪 */ // ...省略具体逻辑... } // 移除当前已处理完毕的key selector.selectedKeys().remove(sk); } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值