NIO作用简介及其相关知识

来源:互联网 发布:网络课程有哪些 编辑:程序博客网 时间:2024/04/30 11:13

NIO基础知识

缓存的概念:

      缓存是硬盘控制器上的一块内存芯片,具有极快的存取速率,它是硬盘内部存储和外界接口之间的缓冲器。由于硬盘的内部数据传输速率和外界介面传输速率不同,缓存在其中起到一个缓冲的作用。缓存的大小与速率是直接关系到硬盘的传输速率的重要因素,能够大幅度地提高硬盘整体性能。当硬盘存取零碎数据时需要不断地在硬盘内存之间交换数据,有大缓存,则可以将那些零碎数据暂存在缓存中,减小系统的负荷,也提高了数据的传输速率

   缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,找到就立即读取并送给CPU处理;没有找到,就用相对慢的速率内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存

NIO概念:

        Java提供了另一套I/O系统,称为NIO(New I/O的缩写)。NIO支持面向缓存的、基于通道的操作。

   NIO系统构建于两个基础术语之上:缓存和通道。缓存用于容纳数据,通道表示打开的到I/O设备(例如文件或套接字)的连接。通常为了使用NIO系统,需要获取用于连接I/O设备的通道以及用于容纳数据的缓存。然后操作缓存,根据需要输入或输出数据

通道:

      Channel是一个对象,可以通过它读取和写入数据。拿NIO与原来的I/O作比较,通道就像是流,与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类),而通道可用于读、写或者同时用于读写。一般是将数据从从通道读入缓冲区,再从缓冲区获取这个字节。

包含NIO类的包:

  1.      java.nio :NIO系统的顶级包,用于封装多种类型的缓存,这些缓存包含NIO系统所操作的数据。
  2.   java.nio.channels:支持通道,通道本质上是打开的I/O连接
  3.   java.nio.channels.spi:支持通道的服务提供者
  4.   java.nio.charset:封装字符集,另外还支持分别将字符转化为字节以及将字节转化为字符的编码器和解码器
  5.   java.nio.charset.spi:支持字符集的服务提供者
  6.   java.nio.file:提供对文件的支持(该包由JDK7新增)
  7.   java.nio.file.attribute:提供对文件属性的支持(该包由JDK7新增)
  8.   java.nio.file.spi:支持文件系统的服务提供者

NIO与传统I/O的区别

传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大。使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数量线程的线程池,甚至一个线程来为任意数量的连接服务。由于线程数量小于连接数量,所以每个线程进行IO操作时就不能阻塞,如果阻塞的话,有些连接就得不到处理,NIO提供了这种非阻塞的能力。

 

小量的线程如何同时为大量连接服务呢,答案就是就绪选择。这就好比到餐厅吃饭,每来一桌客人,都有一个服务员专门为你服务,从你到餐厅到结帐走人,这样方式的好处是服务质量好,一对一的服务,VIP啊,可是缺点也很明显,成本高,如果餐厅生意好,同时来100桌客人,就需要100个服务员,那老板发工资的时候得心痛死了,这就是传统的一个连接一个线程的方式。

 

老板是什么人啊,精着呢。这老板就得捉摸怎么能用10个服务员同时为100桌客人服务呢,老板就发现,服务员在为客人服务的过程中并不是一直都忙着,客人点完菜,上完菜,吃着的这段时间,服务员就闲下来了,可是这个服务员还是被这桌客人占用着,不能为别的客人服务,用华为领导的话说,就是工作不饱满。那怎么把这段闲着的时间利用起来呢。这餐厅老板就想了一个办法,让一个服务员(前台)专门负责收集客人的需求,登记下来,比如有客人进来了、客人点菜了,客人要结帐了,都先记录下来按顺序排好。每个服务员到这里领一个需求,比如点菜,就拿着菜单帮客人点菜去了。点好菜以后,服务员马上回来,领取下一个需求,继续为别人客人服务去了。这种方式服务质量就不如一对一的服务了,当客人数据很多的时候可能需要等待。但好处也很明显,由于在客人正吃饭着的时候服务员不用闲着了,服务员这个时间内可以为其他客人服务了,原来10个服务员最多同时为10桌客人服务,现在可能为50桌,60客人服务了。

 

这种服务方式跟传统的区别有两个:

1、增加了一个角色,要有一个专门负责收集客人需求的人。NIO里对应的就是Selector。

2、由阻塞服务方式改为非阻塞服务了,客人吃着的时候服务员不用一直侯在客人旁边了。传统的IO操作,比如read(),当没有数据可读的时候,线程一直阻塞被占用,直到数据到来。NIO中没有数据可读时,read()会立即返回0,线程不会阻塞。

 

NIO中,客户端创建一个连接后,先要将连接注册到Selector,相当于客人进入餐厅后,告诉前台你要用餐,前台会告诉你你的桌号是几号,然后你就可能到那张桌子坐下了,SelectionKey就是桌号。当某一桌需要服务时,前台就记录哪一桌需要什么服务,比如1号桌要点菜,2号桌要结帐,服务员从前台取一条记录,根据记录提供服务,完了再来取下一条,这样服务的时间就被最有效的利用起来了
















0 0