所谓IO即input和output的缩写,是对数据的流入和流出的一种抽象。
其中NIO
NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区),Selector(选择器)。
Channel(通道):通常NIO的操作都是由通道开始的,channel类似于流,每个channel对应一个buffer缓冲区,buffer底层是个数组。Channel会注册到Selector(选择器),由Selector根据channel读写事件的发生将其交给空闲的线程处理。
Buffer(缓冲区):buffer就是一个数组,本质上相当于一个内存区,读取数据时并不会一个字节一个字节的读取,而是将数据先写入到buffer(缓存区),再统一的写到硬盘上。
Selector(选择器):选择器也可以叫做多路复用器(选择那个线程执行),可以对应一个或多个线程。NIO 的Buffer和Channel都是既可以读也可以写的。
NIO与传统BIO的区别:
传统的的BIO基于字节流或者字符流进行操作 ,而NIO基于Channel和Buffer进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector用于监听多个通道的事件(比如连接打开,数据到达)。因此,单个线程可以监听多个数据通道。
BIO | NIO |
面向流 | 面向缓冲区 |
阻塞IO | 非阻塞IO |
无 | 选择器 |
NIO源码包位于rt.jar下
有名的Netty通信框架就是架设在NIO的基础上的。
Netty三大特性:
1.并发高
Netty是一款基于NIO(Nonblocking IO),非阻塞开发的网络通信框架,对比BIO(Blocking IO),他的并发性能得到了很大的提高。
2.传输快
Java的内存有堆内存、栈内存和字符串常量池等等,其中堆内存是占用内存空间最大的一块,也是Java存放对象的地方。一般我们的数据如果需要IO读取到堆内存,中间需要经过Socket的缓冲区,也就是说一个数据会被拷贝两次才能到达他的终点,如果数据量大,就会造成不必要的资源浪费。
Netty针对这种情况,使用了NIO中的另一大特性–零拷贝,当他需要接受数据时,他就会直接从IO读到了那块内存中去,在netty里面通过ByteBuf可以直接对这些数据进行直接操作,从而加快了传输速度。
3.封装性,对NIO进行了透明化封装,形成框架,开箱即用。