NIO学习笔记(一)——NIO的特点介绍

来源:互联网 发布:工作总结工作计划知乎 编辑:程序博客网 时间:2024/06/03 21:43

什么是NIO?

大家可能看到名字就能联想到IO,的确,NIO和IO有着一定的关系。

NIO是一套全新的IO框架,可是原来我们已经有了一套IO框架了,为什么sun公司又要推出这么一款全新的NIO框架呢?

可以说,每一个拥有面向对象设计理念和设计思想的Java程序员,在回头看以往的IO框架,也就是InputStream和OutputStream这一块的内容的时候,都会觉得这一块内容设计得其实有一些不合理之处。但这些不合理并没有达到不可用的地步,直到现在,传统的IO也没有被彻底地放弃,而且仍然在被广泛地应用。

但是在那个年代,Sun公司作为技术领先的一个公司,在JDK1.4中加入了一个新的NIO框架。NIO框架在当年有着一些很超前的理念,但是由于各种各样的一些形式的限定,比如说在2002年(大概是JDK1.4发布的时间),互联网不是十分发达,大家也没有深入理解到高并发带来的困扰,并且这一套NIO框架也并不是那么好用。以至于在JDK1.4以后的若干版本中,NIO都不是很闪亮的一个点,并没有被大家所重视。现在一些主流的Java教程中,也没有专门的关于NIO的板块,甚至没有提及NIO的存在。在JDK7以后,也就是Oracle公司接手Sun公司后Java的第一个大版本中,NIO得到了显著的增强。它作为一个设计亮点,在JDK7中被浓墨重彩地渲染了一把。在我看来,Sun公司在技术上是一个很领先的公司,但在技术的包装上的确是有那么一点欠缺。

说了那么多NIO的历史,为什么我们要学习NIO这个框架呢?要回答这个问题,我们就不得不提一下传统IO框架的一些弊端。NIO的N有两种解释,一种是Nonblock——非阻塞。还有一种解释是New,这种解释就非常通俗易懂,新的IO。NonBlock其实是对它的特性进行描述,NonBlock对应的就是Block。传统的IO其实就是一种阻塞的IO,大家在使用传统IO的时候应该都注意到了,在流的读写过程中,当前线程是会被挂起的,最典型的应用就是在Socket编程中,Socket一旦建立起InputStream或者OutputStream这种流的关系以后,如果另一方没有传递过来数据,或者我这边数据没有写完,那么整个线程的资源都会被占用,下面的所有内容都不会被执行,直到我显式地去close这个流,或者说有一端出现了IOException。那么这个NIO它提出的是一种非阻塞的IO,也就是说我们可以在一种不需要阻塞线程的情况下去读写数据,而达到一些更高效的IO操作。

NIO看似有很多的功能点,其实核心组件只有三个——channel、buffer和selector。

我们通过一张图来理解NIO和IO的区别:

NIO和IO原理对比

传统的IO读和写是用不同的类来处理的,也就是说,我回家的路和上班的路是不同的。这体现出了这样一个设计时问题,这个InputStream和OutputStream是不是应该被设计出一个上层抽象,把它们统称为一个“连接”。NIO中其实就是实现了这么一个思想。NIO的框架中没有输入流和输出流的概念,它们统称为channel。它也分为读和写,但是读和写都是基于channel而言的,它不再进一步分为两个对象,而是既能读也能写。

InputStream和OutputStream在进行操作的时候是基于byte数组来操作的,channel在工作的时候依赖的是buffer对象,也就是说channel在进行读写的时候都要依赖于buffer来完成。这个buffer其实也不难理解,在我们使用传统IO的时候,经常也会使用缓冲流,或者自己写一个byte数组,来完成流的读写操作。只是在NIO当中,这成为了一个必然。也就是说,在流的两端间建立起channel,read的时候,可以把流中的数据read到buffer中,而write的时候,也是同样把buffer中的内容write到目的地。至此有了channel和buffer以后,我们的NIO就可以完成一些基本的操作了。

原创粉丝点击