NIO是为了弥补IO操做的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道。管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征。服务器
概念解释:并发
Channel——管道实际上就像传统IO中的流,到任何目的地(或来自任何地方)的全部数据都必须经过一个 Channel 对象。一个 Buffer 实质上是一个容器对象。线程
Selector——选择器用于监听多个管道的事件,使用传统的阻塞IO时咱们能够方便的知道何时能够进行读写,而使用非阻塞通道,咱们须要一些方法来知道何时通道准备好了,选择器正是为这个须要而诞生的。对象
NIO和传统的IO有什么区别呢?事件
1,IO是面向流的,NIO是面向块(缓冲区)的。资源
IO面向流的操做一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。,致使了数据的读取和写入效率不佳;get
NIO面向块的操做在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多,同时数据读取到一个它稍后处理的缓冲区,须要时可在缓冲区中先后移动。这就增长了处理过程当中的灵活性。通俗来讲,NIO采起了“预读”的方式,当你读取某一部分数据时,他就会猜想你下一步可能会读取的数据而预先缓冲下来。it
2,IO是阻塞的,NIO是非阻塞的。io
对于传统的IO,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据彻底写入。该线程在此期间不能再干任何事情了。效率
而对于NIO,使用一个线程发送读取数据请求,没有获得响应以前,线程是空闲的,此时线程能够去执行别的任务,而不是像IO中那样只能等待响应完成。
3,NIO和IO适用场景
NIO是为弥补传统IO的不足而诞生的,可是尺有所短寸有所长,NIO也有缺点,由于NIO是面向缓冲区的操做,每一次的数据处理都是对缓冲区进行的,那么就会有一个问题,在数据处理以前必需要判断缓冲区的数据是否完整或者已经读取完毕,若是没有,假设数据只读取了一部分,那么对不完整的数据处理没有任何意义。因此每次数据处理以前都要检测缓冲区数据。
那么NIO和IO各适用的场景是什么呢?
若是须要管理同时打开的成千上万个链接,这些链接每次只是发送少许的数据,例如聊天服务器,这时候用NIO处理数据多是个很好的选择。
而若是只有少许的链接,而这些链接每次要发送大量的数据,这时候传统的IO更合适。使用哪一种处理数据,须要在数据的响应等待时间和检查缓冲区数据的时间上做比较来权衡选择。
4,通俗解释
最后,对于NIO和传统IO,有一个网友讲的生动的例子:
之前的流老是堵塞的,一个线程只要对它进行操做,其它操做就会被堵塞,也就至关于水管没有阀门,你伸手接水的时候,无论水到了没有,你就都只能耗在接水(流)上。
nio的Channel的加入,至关于增长了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各个水管里流出来的水,均可以获得妥
善接纳,这个关键之处就是增长了一个接水工,也就是Selector,他负责协调,也就是看哪根水管有水了的话,在当前水管的水接到必定程度的时候,就切换一下:临时关上当前水龙头,试着打开另外一个水龙头(看看有没有水)。
当其余人须要用水的时候,不是直接去接水,而是事前提了一个水桶给接水工,这个水桶就是Buffer。也就是,其余人虽然也可能要等,但不会在现场等,而是回家等,能够作其它事去,水接满了,接水工会通知他们。
这其实也是很是接近当前社会分工细化的现实,也是统分利用现有资源达到并发效果的一种很经济的手段,而不是动不动就来个并行处理,虽然那样是最简单的,但也是最浪费资源的方式。