跟我学系列之趣解NIO和IO的区别

本文通过生动的故事形式对比了传统IO与NIO的工作方式。在传统IO中,管理员需等待动物吃完水果才能继续工作;而在NIO中,管理员可以利用等待时间完成其他任务,大大提高了效率。

在上一次分享中,咱们谈到了阻塞与非阻塞,同步与异步的区别,http://www.jianshu.com/p/e9c6690c0737

那么在这一次分享中,咱们主要是以讲故事的方式讲述一下NIO和IO的区别。那么在下一次分享中,将进行Java NIO源码的分析。

故事的背景:

有一个动物园,动物园里面有狮子,老虎,猴子等动物,他们每天定期来吃不同的水果,而这些水果要由动物园管理员到货场领取分配。

一、IO

我们知道,在使用IO的时候往往可以在服务器端使用多线程或者线程池来处理并发请求,这也叫伪异步,那么故事开始了:

在货场里有五个动物园管理员等待水果货车的到来,他们一直在等待,如果货车不来他们也要死等,直到货车的到来,这时候货车来了,每个管理员都领了一份水果去寻找动物,管理员A来到狮子旁边,给狮子一份苹果,狮子开始吃,中途吃累了,休息了一会儿继续吃,这时候管理员A就一直等着狮子吃完,再回去拿水果去另一个动物那里。五个管理员都是这样做的。

二、NIO

Java NIO是在jdk1.4开始使用的,它既可以说成“新IO”,也可以说成非阻塞式I/O。下面是java NIO的工作原理:

由一个专门的线程来处理所有的IO事件,并负责分发。

事件驱动机制:事件到的时候触发,而不是同步的去监视事件。

线程通讯:线程之间通过wait,notify等方式通讯。保证每次上下文切换都是有意义的。减少无谓的线程切换。

那么故事开始了:动物园里,有一个管理员他先去了解动物们都喜欢吃什么样的水果并做了一个登记,然后去货场看一看货车有没有到来,如果没有来他就回去继续干别的事,就这样每隔一段时间就去货场看一下。这时候货车来了,他叫来另外五个管理员并告诉管理员哪些动物喜欢吃哪些水果,管理员们分类取不同的水果,然后各自去找动物们分发水果,还是管理员A,来到狮子旁边把它喜欢吃的苹果给它吃,狮子吃的比较慢,这时候管理员A说,你先吃着,我给其他动物送水果,我一会儿再来取水果盘子,这时候管理员A回去取来香焦继续猴子送去,在猴子吃香焦累了休息的时候,管理员A来找狮子拿回水果盘子,再去找猴子拿回水果盘子。

不知道大家在看完这二个小故事之后有没有理解NIO和IO,那么在下次分享的时候,咱们将正式进入NIO原理及源码的分享,谢谢大家。

<think>好的,我现在需要回答用户关于JavaNIOIO区别的问题。首先,我需要回顾一下用户提供的引用内容,看看有什么可以使用的信息。 用户提供了五个引用,其中引用[1]到[4]主要讨论了NIOIO的主要差异,包括面向流与面向缓冲区、阻塞与非阻塞IO、选择器(Selectors)等。引用[5]提到了连接超时相关的异常,但可能核心区别关联不大,暂时可以忽略。 首先,我需要整理出NIOIO的主要区别点。根据引用[1][3],主要差异包括: 1. **流导向 vs 缓冲区导向**:IO是面向流的,每次从流中读取一个或多个字节,直到读取完毕,不能前后移动流中的数据。而NIO是面向缓冲区的,数据读取到一个缓冲区,可以在缓冲区中前后移动,增加了灵活性。 2. **阻塞与非阻塞IO**:IO是阻塞的,当线程调用读写方法时,线程会被阻塞直到操作完成。而NIO允许非阻塞模式,线程可以继续做其他事情,如果数据未准备好,线程可以处理其他通道的IO操作。 3. **选择器(Selectors)**:NIO引入了选择器的概念,允许一个线程监视多个通道的事件(如连接打开、数据到达),提高了处理多通道的效率。 接下来,我需要将这些点详细展开,确保结构清晰。同时,要使用中文,并遵循用户给出的格式要求,比如行内数学表达式用$...$,独立公式用$$...$$,不过在这个问题中可能不太涉及数学公式,所以可能不需要使用。另外需要生成相关问题,放在最后。 需要确保回答正确,所以可能需要验证一下每个差异点的准确性。例如,确认NIO的缓冲区工作方式,以及选择器如何管理多个通道。同时,要参考用户提供的引用,比如引用[4]中的表格,确保信息一致。 然后,生成相关问题需要考虑用户可能进一步想了的内容,比如性能比较、使用场景、如何选择等。例如: 1. Java NIO在哪些场景下比传统IO更高效? 2. 如何在实际项目中选择使用NIO还是IO? 3. NIO的非阻塞模式如何实现多路复用? 最后,检查是否符合用户的所有要求,包括引用标注,比如在提到流缓冲区差异时加上引用[^3],在非阻塞部分加上引用[^4]等。 现在,将这些思考整理成结构化的回答,确保每个部分清晰,并且自然引用相关内容。</think>### Java NIOIO的核心差异 Java中的NIO(New I/O)与传统IO在设计理念实现方式上有显著差异,主要体现在以下三个方面: --- #### 1. **数据操作方式** - **IO:面向流(Stream Oriented)** 每次从流中顺序读取1个或多个字节,数据不能前后移动。例如读取文件时,需逐个字节处理,直到流结束[^3]。 ```java InputStream in = new FileInputStream("file.txt"); int data = in.read(); // 阻塞读取单个字节 ``` - **NIO:面向缓冲区(Buffer Oriented)** 数据首先被读取到缓冲区(如$ByteBuffer$),程序可直接操作缓冲区中的数据(如前后移动指针),支持批量处理[^4]。 ```java ByteBuffer buffer = ByteBuffer.allocate(1024); channel.read(buffer); // 数据填充到缓冲区 buffer.flip(); // 切换为读模式 ``` --- #### 2. **I/O模型** - **IO:阻塞式(Blocking IO)** 线程调用读写方法时会被阻塞,直到数据就绪或操作完成。例如,`read()`方法会阻塞线程直到有数据可读[^3]。 - **NIO:非阻塞式(Non-blocking IO)** 线程可注册多个通道到选择器(Selector),通过轮询检查哪些通道已就绪。未就绪时,线程可处理其他任务,避免阻塞[^4]。 ```java channel.configureBlocking(false); Selector selector = Selector.open(); channel.register(selector, SelectionKey.OP_READ); ``` --- #### 3. **多路复用与选择器** - **NIO的选择器(Selector)** 允许单个线程监控多个通道的I/O事件(如连接、读取、写入),显著减少线程资源消耗。例如,一个服务器可通过一个线程处理数千个客户端连接[^4]。 --- #### 核心差异总结表 | **特性** | **IO** | **NIO** | |------------------------|-----------------------|-----------------------------| | 数据操作方式 | 面向流 | 面向缓冲区 | | 线程阻塞 | 完全阻塞 | 可非阻塞(依赖选择器) | | 多通道管理 | 需多线程 | 单线程多路复用 | | 适用场景 | 低并发、简单I/O | 高并发、网络服务器 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值