http://www.zhihu.com/question/19732473
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻。
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大。
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。
所谓同步异步,只是对于水壶而言。
普通水壶,同步;响水壶,异步。
虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。
立等的老张,阻塞;看电视的老张,非阻塞。
情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
===========================
个人理解,上面的买书的例子有点牵强,我改编一下:
异步/同步:
异步: 你去书店,问《如何征服美少女》到货没,老板说,没到货,到货了给你打电话。你就走了,而且不需要再没接到老板电话之前再跑到书店问。
同步:你去书店,问《如何征服美少女》到货没,老板说,没到货,你走了,过了一段时间,你又到书店,问《如何征服美少女》到货没,老板说没有,。。。。就这样,你不断的来书店自己询问。直到你鞋都跑破了.....
注意:你离开书店(不管是异步还是同步),是可以干自己的事情的,比如去做个大保健。
阻塞/非阻塞
阻塞:你去书店,问《如何征服美少女》到货没有,老板说,没到货,于是你就在书店苦等,等书到货,除了干坐着,啥也干不了,直到书来。
非阻塞:你去书店,问《如何征服美少女》到货没,老板说,没到货,你就走了。(至于还来不来书店,取决于你的心情吧。但是在计算机中,没处理完的事情,是要处理的。)
异步/同步 是你的到消息的方式。
阻塞/非阻塞是你怎样处理事情。
两组概念不是一个层面上的。
在上面的例子中,你就相当于计算机中的 进程 ,你的两条腿就相当于CPU。(比喻很牵强也)
===========================
首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作。
同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO服用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。
阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
===========================
简单点来说:同步和异步关注的是消息通信机制。
所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由*调用者*主动等待这个*调用*的结果。
而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。