NIO,同步异步,阻塞非阻塞

1、我们何时使用IO,何时使用NIO呢?这两者有三个差异:

1) IO面向流,NIO是面向缓冲区的,IO面向流意味着每次从流中读一个或多个字节,直到读取所有字节,它们没有被缓存在任何地方。此外它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。NIO的缓冲导向方法略有不同,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。增加了处理过程中的灵活性。

2)IO流是阻塞的,这意味着,当一个线程调用read()write()时,该线程被阻塞,该线程在此期间不能再干任何事情了。NIO是非阻塞模式的,使得一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直到数据变的可以读取之前,该线程可以继续做其他的事情。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道。

3)NIO有选择器,可以注册多个通道使用一个选择器,允许一个单独的线程监视多个输入输出通道。

   NIO由以下几个核心组成BufferChannel,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函数监听所有channel的操作是否就绪,当channel中有事件就绪时,就会返回。

2、同步和异步:

是指线程之间的关系,两个线程之间要么是同步,要么是异步的。

同步:发出一个调用时,在没有得到结果前,该调用就不返回,得到结果后才会返回。异步:调用在发出之后就直接返回,即一个调用发生后,调用者不会立即得到结果,而是在调用发生后,如果有消息返回,系统会通知调用者进行处理。

3、阻塞和非阻塞

是对同一个线程来说的,在某个时刻,线程要么阻塞,要么处于非阻塞。阻塞是使用同步机制的结果,非阻塞是使用异步机制的结果

 

4、AIO和BIO

BIO是同步阻塞的,是最简单的IO模型,用户线程在内核进行IO操作时被阻塞。整个IO请求过程中,用户线程是被阻塞的,导致用户不能做任何事情

AIO是异步非阻塞的,应用操作之后会直接返回,不会阻塞,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

 

posted @   MarkLeeBYR  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示