关于这个话题,网上有很多文章写的很好,这里主要做一个总结,谈谈我个人的理解。
相关参考文章:
IO - 同步,异步,阻塞,非阻塞(亡羊补牢篇)
Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式
网络IO之阻塞、非阻塞、同步、异步总结
在开始讨论之前,先限定本文的讨论范围:
- 这里的阻塞是指IO的阻塞,不是操作系统中线程的生命周期中的阻塞,那个是指失去了CPU时间片,这里认为“阻塞”是影响业务处理了
- 站在宏观的角度,主要讨论思想,不深入细节
对于阻塞/非阻塞,同步/异步,我个人的理解是:
- 阻塞,非阻塞,指能否对新的请求进行响应。比如上篇文章中的例子,传统IO是阻塞的,因为其在读取数据时,无法对新的请求进行响应;NIO就是非阻塞的,其在读取数据时,能对新的请求进行响应。
- 同步,异步,指IO操作是否由主线程完成。比如上篇文章中的IO NIO都是同步的,因为IO操作是由主线程自己完成的;异步时IO操作是由操作系统的内核完成的,主线程只负责发出命令,接受完成通知。
- 异步就是为了非阻塞,所以谈异步阻塞是没有意义的
在上面几点理解的基础上,我们来看看常见的各种"IO名词"
BIO,同步阻塞IO,比如传统IO操作
NIO,同步非阻塞IO,比如select epoll
AIO,异步IO
更具体的例子,可以参看上一篇文章。
有些文章将阻塞/非阻塞定义为:调用后是否能够立即返回。
我认为首先“立即返回”容易让人想要量化“立即”这个判断依据,1ms 100ms 1s到底那个算是立即呢?其次,立即返回并不是一个目的,IO没干完,返回了对我来说也没用啊,真正的目的是为了不影响后面的操作。所以我认为将非阻塞定义为能否响应新的请求更合适。
关于同步/异步,也有文章定义为:后面的任务必须等待前面的任务执行完才能执行。
我认为任务的执行顺序,只是一种现象,正是因为主线程让别人帮他干活,才导致不用等前面的任务完成,后面的任务也可以执行。所以我认为将异步定义为目标操作是否由主线程完成更合适。
关于概念的认识,重点还是理解思想,可能在具体的表达上,每个人都有自己的想法,但是无关对错,只要自己能理解就行。