形象的说明
如果你想吃一份宫保鸡丁盖饭:
同步阻塞:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊!
同步非阻塞:在饭馆点完餐,就去遛狗了。不过溜一会儿,就回饭馆喊一声:好了没啊!
异步阻塞:遛狗的时候,接到饭馆电话,说饭做好了,让您亲自去拿。
异步非阻塞:饭馆打电话说,我们知道您的位置,一会给你送过来,安心遛狗就可以了。
结合 IO 说明
同步阻塞 IO:
在此种方式下,应用发起一个 IO 操作以后,必须等待 IO 操作的完成,只有当真正完成了 IO 操作以后,用户进程才能继续运行。JAVA 传统的 IO 模型属于此种方式!
同步非阻塞 IO:
在此种方式下,应用发起一个 IO 操作以后便可返回做其它事情了,但是用户进程需要时不时的询问 IO 操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的 CPU 资源浪费。目前 Java 的 NIO 就属于同步非阻塞 IO。
异步阻塞 IO:
在此种方式下,应用发起一个 IO 操作以后,不必等待内核 IO 操作的完成,IO 完成后会通知应用程序。
这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问 IO 是否完成。
那么为什么说是阻塞的呢?因为此时是通过 select 系统调用来完成的,而 select 函数本身的实现方式是阻塞的,而采用 select 函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!
异步非阻塞 IO:
在此种方式下,应用只需要发起一个 IO 操作然后立即返回,等 IO 操作真正的完成以后,应用程序会得到 IO 操作完成的通知或回调,此时用户进程只需要对数据进行处理就好了,不需要进行实际的 IO 读写操作,因为真正的 IO 读取或者写入操作已经由内核完成了。