1、我们何时使用IO,何时使用NIO呢?这两者有三个差异:1) IO面向流,NIO是面向缓冲区的,IO面向流意味着每次从流中读一个或多个字节,直到读取所有字节,它们没有被缓存在任何地方。此外它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。NIO的缓冲导向方法略有不同,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。增加了处理过程中的灵活性。2)IO流是阻塞的,这意味着,当一个线程调用read()或write()时,该线程被阻塞,该线程在此期间不能再干任何事情了。NIO是非阻塞模式的,使得一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直到数据变的可以读取之前,该线程可以继续做其他的事情。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道。3)NIO有选择器,可以注册多个通道使用一个选择器,允许一个单独的线程监视多个输入输出通道。
NIO由以下几个核心组成:Buffer,Channel,Selector,传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,甚至完成,数据没有被缓存在任何地方。NIO操作面向缓冲区,数据从Channel读取到Buffer缓冲区,随后在Buffer中处理数据。下面介绍了Buffer和Channel的概念以及在文件读写方面的应用和内部实现原理。
1)Buffer:一块缓存区,内部使用字节数组存储数据,并维护几个特殊变量,实现数据的反复利用。注意通常说NIO的读操作,我们说的是从Channel中读数据到Buffer中,对应的是Buffer的写入操作
Nio定义了以下几个Buffer的实现,核心是最后的ByteBuffer,前面的一大串类只是包装了一下它而已,我们使用最多的也是ByteBuffer
我们应该把Buffer理解为一个数组,IntBuffer、CharBuffer和DoubleBuffer分别对应int[]、char[]和double[]等
2)Channel:Channel是对原IO中流的模拟,发给channel的所有对象都要先放到buffer中,同样的从channel中读取的任何数据都要读到buffer中。和原I/O中的流有所区别,主要在于:1.流读写是阻塞的,通道可以异步读写。2.流中的数据直接写入到stream对象,对channel的读写必须经过buffer。3.channel是双向的,既可读又可写,io流是单向的。
3)Selector:Selector对象可以注册很多channel,监听各个channel发生的事情。有了Selector就可以用一个线程处理所有channel。IO多路复用实际上就是用select函数监听多个IO对象,当IO对象有数据的时候就通知用户进程,当用户进程调用了select,那么整个进程会被阻塞
2、同步和异步:
是指线程之间的关系,两个线程之间要么是同步,要么是异步的。
同步:发出一个调用时,在没有得到结果前,该调用就不返回,得到结果后才会返回。异步:调用在发出之后就直接返回,即一个调用发生后,调用者不会立即得到结果,而是在调用发生后,如果有消息返回,系统会通知调用者进行处理。
3、阻塞和非阻塞
是对同一个线程来说的,在某个时刻,线程要么阻塞,要么处于非阻塞。阻塞是使用同步机制的结果,非阻塞是使用异步机制的结果
4、AIO和BIO
BIO是同步阻塞的,是最简单的IO模型,用户线程在内核进行IO操作时被阻塞。整个IO请求过程中,用户线程是被阻塞的,导致用户不能做任何事情
AIO是异步非阻塞的,用户发起read请求,去做其他事情,当用户线程收到通知时,数据已经被内核读取完毕,并放在指定的缓冲区里,内核在IO完成后通知用户线程直接使用即可
标签:异步,NIO,Buffer,阻塞,线程,IO From: https://www.cnblogs.com/MarkLeeBYR/p/17114065.html