同步、异步、阻塞和非阻塞
本文主要是个人总结,可能有误!因为有关这几个概念,网络上的表述虽大同小异但众说纷纭,只能按自己的理解再总结一遍。
表面上看,同步和阻塞都是没干完,就等着干完;异步和非阻塞都是没干完,先干别的吧,好像很类似!
实际上,同步和异步是对调用方而言,比如说同步函数、异步函数,异步函数里有个参数是回调函数;
而阻塞、非阻塞都是对处理方(被调用方)而言,针对的是线程。阻塞,就是还没有结果,将线程挂起。线程挂起以后,就是处于死等的状态;非阻塞,还没有结果,线程不挂起,可以继续做别的。
如果从范围大小看,同步异步要大于阻塞非阻塞。同步机制里面,线程可以阻塞,也可以非阻塞。就是说,我这个调用,是同步的,去办一件事,一定要办成一个结果才返回。但在办事的过程中,我可以响应其他事。
同理异步方面,也有阻塞非阻塞之分。
编一个故事来区分这几个概念:
入冬,冷空气来袭,天气反复,有一个小朋友病了,父母带他去看医生。
首先要挂号。母亲抱着小朋友,让父亲去挂号(开辟了一个线程)。
情况1、孩子高烧,母亲很担心孩子的病情,心急如焚,就在旁边等父亲挂好号,然后一起去看医生。过程中她心乱如麻,脑子基本一片空白,一心盼望父亲快点挂完号。这就是同步。
情况2、孩子没有发烧,只是有点咳嗽、流涕,应该是小感冒而已。母亲不怎么担心,她对父亲说,你先去拿个号,好了再叫我们。然后自己就带小孩到医院大院里的儿童设施里玩去了。这就是异步。
情况a 父亲也很担心孩子病情,并且排队挂号的人很多,整个过程中他就一直盯着前面,希望队伍挪动得快一点,也生怕有人插队。以致有小偷掏他口袋,他也浑然不觉。这时,他这个线程处于挂起状态。这就是阻塞。
情况b 父亲毕竟是个男子汉,他认为儿子没有这么娇贵。所以他掏出手机,边排队边玩手机。期间他还接了几个电话,谈了一次工作,安排了一个饭局。他这个线程保持激活,随时对外界做出反应。这就是非阻塞。
情况a 和 情况b 放在情况一里,就是同步阻塞或同步非阻塞;放在情况二里,就是异步阻塞或异步非阻塞。
参考文章:
http://kalogen.iteye.com/blog/670841
http://www.zhihu.com/question/19732473
================================================================
有必要再仔细解释一下线程阻塞
什么叫阻塞(block)?线程在执行中如果遇到I/O操作(磁盘读写、网络通信等)通常需要耗费较长的时间,这时候操作系统会剥夺线程对CPU的控制权,使其暂停,并把资源让给其它的工作线程,这种线程调度方式成为阻塞。当I/O操作完毕的时候操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行,这种I/O模式就是同步I/O或成为阻塞I/O。
线程非阻塞,就是把耗时长的工作交出去,给操作系统或别的对象,然后该线程继续往下执行。交出去的工作部分,执行完毕后以某种方式(比如事件)再通知原来的线程。