🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # Unix的IO模型 * **异步I/O** 是指用户程序发起IO请求后,不等待数据,同时操作系统内核负责I/O操作把数据从内核拷贝到用户程序的缓冲区后通知应用程序。数据拷贝是由操作系统内核完成,用户程序从一开始就没有等待数据,发起请求后不参与任何IO操作,等内核通知完成。 * **同步I/O** 就是非异步IO的情况,也就是用户程序要参与把数据拷贝到程序缓冲区(例如java的InputStream读字节流过程)。 * **同步IO里的非阻塞** 是指用户程序发起IO操作请求后不等待数据,而是调用会立即返回一个标志信息告知条件不满足,数据未准备好,从而用户请求程序继续执行其它任务。执行完其它任务,用户程序会主动轮询查看IO操作条件是否满足,如果满足,则用户程序亲自参与拷贝数据动作。 ![](https://box.kancloud.cn/b13ac1449b1506177693ed9b828b6f23_450x157.png) ![](https://box.kancloud.cn/2fd1bf6a6019e4850fa4ebac4a613d69_586x320.png) 简单说,Unix IO模型的语境下,同步和异步的区别在于数据拷贝阶段是否需要完全由操作系统处理。阻塞和非阻塞操作是针对发起IO请求操作后是否有立刻返回一个标志信息而不让请求线程等待。基于这个语境,Netty目前的版本是没有把IO操作交过操作系统处理的,所以是属于同步的。对于网上大部分文章,如果别人说Netty是异步非阻塞,如果要深究,那真要看看Netty新的版本是否把IO操作交过操作系统处理,或者看看有否使用JDK1.7中的AIO API,否则他们说的异步其实是指**客户端程序调用Netty的IO操作API“不停顿等待”。** ===== 其次,在Java的IO模型里: JDK的各个历史版本引入如下概念。 **BIO**: Blocking IO **NIO**:Non Blocking IO 或者 New IO **AIO**:Asynchronous IO 或者 NIO2 这里的AIO应该就对应着Unix模型里的异步IO,也就是IO操作交给操作系统处理,充分调用OS参与并发操作,确实是操作系统的异步IO机制。 而BIO和NIO简单对比就是,NIO解决了BIO的痛点,把BIO中请求IO过程中的两步(请求连接+连接有真实IO请求时候的处理过程)分离开来,不让一个线程负责这两步。NIO就是一个线程负责所有请求连接但不处理IO操作,该线程只负责把连接注册到多路复用器上,多用复用器轮询到连接有IO请求时候再启动其它线程处理IO请求操作。 注意一点,Netty线程模型提及很多IO线程池,每条IO线程在进行IO操作(IO条件满足进行真正读写数据)时候虽然也是要消耗操作时间,但这种情况是否应该叫阻塞,取决于该IO线程有没有阻塞业务请求线程,当且仅当所有的IO线程在重度负载情形下(IO线程池所有IO线程在工作)导致业务请求线程提交不了新请求的情形下才叫IO线程的IO操作阻塞了业务线程的IO请求。由此可知,NIO也会产生BIO的情况。