一 NIO简介
Java NIO 是 java 1.4 之后新出的一套IO接口,其中新是相对于原有标准的Java IO和Java Networking接口。NIO提供了一种完全不同的操作方式。
NIO中的N可以理解为Non-blocking,不单纯是New。
它支持面向缓冲的,基于通道的I/O操作方法。 随着JDK 7的推出,NIO系统得到了扩展,为文件系统功能和文件处理提供了增强的支持。
由于NIO文件类支持的这些新的功能,NIO被广泛应用于文件处理。对于NIO流,其相比于之前IO而言最大的特点有:具有缓冲区,非阻塞IO,引入选择器。
线程之间的切换对于操作系统来说是昂贵的。 而选择器用于使用单个线程处理多个通道。因此,它需要较少的线程来处理这些通道。避免线程切换带来的性能损耗。
对于缓冲区,非阻塞IO在此便不赘述,字面意思解读即可。
二 NIO核心组件
之前我们IO读取都是直接获取输出/输出流后再进行内容读取,而NIO中的所有IO都基于Channel(通道) 传输。
从通道进行数据读取 :创建一个缓冲区,然后请求通道读取数据。
从通道进行数据写入 :创建一个缓冲区,填充数据,并要求通道写入数据。
因此,在NIO中常见的核心组件有:
- Channels
-
Selectors
-
Buffers
-
对于Buffer你完全可以看做是一个数据存放容器,是可以理解为一个个“数据块”信息,我们可以对其进行读写操作。
Buffer实质上是一个数组,但对于缓冲区而言其不仅仅是一个数组,更重要的是它提供了对数据的结构化访问。
对于channel则负责传输缓冲区Buffer中的数据块,如果说Buffer可以比作码头的话,码头中的一个个集装箱,就是存放在Buffer中的数据块,而channel就是航道,运输这些集装箱,就需要走我们的航道,将集装箱送到目的地的码头,具体去哪个码头取集装箱,是由航道决定的,这条航道通往哪里,你就去哪个码头。
所以,如果我们获取集装箱(数据块)是去找码头(Buffer),找码头(Buffer)之前,我先需要通过航道(Channel)把数据块读入运入(读入)码头。
最后对于Selector选择而言,如果我们把Buffer缓冲区看做码头,Channel通道看做航道的话,那么Selector选择器可以看做海上的一个调度中心,一个调度中心可以监听多个航道的事件,当然,这需要航道归属在这个调度中心的编制下。
其实Selector是一个对象,它可以被注册到很多个Channel上,监听各个Channel上发生的事件,并且能够根据事件情况决定Channel读写。这样,通过一个线程管理多个Channel,就可以处理大量网络连接了。
通过上述分析我们不难总结出编写NIO时的大致思路,第一步构建出调度信息的Selector便于航道信息的监听,第二步构建出我们所需要的航道,即Channel信息,此时为了能事实检测航道数据传送情况,我们就需要将Selector注册到Channel之上。
工作机制
常见初始化构建流程
读取数据信息
读取数据思路大致就是:获取到“航道”,构建出“数据块”信息,调用"航道"read()方法,即可将信息填充至数据块中,随后转成字符串即完成信息的读取。
此时可能涉及一个Selectionkey的陌生信息,这个其实可以理解为我们向通道上的注册监听的事件信息,通过其中的channel方法即可获取到开辟的“航道”信息。
三 总结
本文主要对NIO的基本特性,核心组件进行了大致分析,同时总结出了使用NIO的基本流程信息,其中的Buffer,Channel,Selector其实还有很多细节内容,后续文章也逐一对其分析和拆解。
希望文章能对你带来些帮助和启发,有任何问题均可私信交流。