NIO、BIO、AIO 待我称王封你为后i 2022-10-10 15:54 211阅读 0赞 # IO模型 # ### 文章目录 ### * IO模型 * * 一、同步、异步 * 二、数据读取的过程 * 三、同步阻塞、同步非阻塞、同步多路复用、异步非阻塞 ## 一、同步、异步 ## * 同步:线程自己去发起请求,获取结果(一个线程) * 异步:线程自己发起结果,但不去获取结果,而是由其它线程获取结果后发送给这个线程(至少两个线程) ## 二、数据读取的过程 ## 当用户线程调用 `channel.read` 或 `stream.read` 后,会切换至操作系统内核态来完成真正的数据读取,而读取又分为两个阶段,分别为: * 等待数据阶段 * 复制数据阶段 ![image-20210625110539696][] ## 三、同步阻塞、同步非阻塞、同步多路复用、异步非阻塞 ## * 阻塞 IO(同步)(BIO) * 用户线程被阻塞,调用read方法后,在等待内核空间读取数据的时间内,不能进行其他操作,只能等待 ![image-20210625110642843][] * 非阻塞 IO(同步) * 用户线程不会被阻塞,调用read方法后,即使内核空间没有读取到数据,会返回0,用户线程循环调用 `read` 方法,不会阻塞,直到复制阶段才被阻塞 * 数据的复制阶段仍然是阻塞的 ![image-20210625110722976][] * 多路复用(同步,单个线程配合selector使用)(NIO) * 阻塞直到事件发生 * 在等待阶段和复制阶段都会阻塞(单个channel的角度看,是阻塞的) * 多个channel的角度看,是非阻塞的,一个channel中没有数据,不会阻塞,可以处理其他channel ![image-20210625110747910][] * 异步非阻塞(异步 IO)(AIO) * 用户调用read方法之后,内核空间立刻返回,告知得到用户的请求,等内核空间完成对应的操作之后,由另一个线程将结果返回 * 内核空间完成操作之后,会调用回调方法回传数据 * 由于立刻返回,所以异步一定不是阻塞,故异步一定是非阻塞的 ![image-20210625110812252][] * 阻塞 IO vs 多路复用(均为同步) * 阻塞IO,处理一个连接的时候不能处理另一个连接,如果想要处理一个新的连接,必须等到上次的连接完全处理结束之后才可以处理新的连接 * 多路复用,一个 selector 可以同时处理多个 channel 的事件,某个 channel 中没有数据时,线程无需等待,可以处理其他事情 ![image-20210625110955834][] [image-20210625110539696]: /images/20221005/0edeb72f447c426cbf1f717180fb4c82.png [image-20210625110642843]: /images/20221005/add2af9394ad4ed2a7014e7b9c4f5385.png [image-20210625110722976]: /images/20221005/9c54eec2d9d14c67900642e9d644bf8c.png [image-20210625110747910]: /images/20221005/c5bd188200254839bd86ffb96824bad5.png [image-20210625110812252]: /images/20221005/7ecdf6a30e67489b846ace8f87cfe22e.png [image-20210625110955834]: /images/20221005/b5c26bcb179a4a33921b7ae97759716f.png
还没有评论,来说两句吧...