相信干IT的或多或少都听说过同步、异步、阻塞、非阻塞这四个词,它们也可以分成两对,也就是同步、异步一对,阻塞、非阻塞一对,这个看词义就很好理解。关键问题在于同步和阻塞、异步和非阻塞之间的区别,很多人对这两组概念有点分不清,感觉意思差不多,其实它们描述的是两个不同的问题,我们用一个具体的场景来描述一下这四个词,用真实的生活场景感受一下它们的不同。
我们应该都有过去银行柜台办理业务的经历,当人很多的时候往往要排队等待,那么这时候就可能出现这四种情况:
在柜台前排队(同步),在排队过程中不做任何其他事情(阻塞);
在柜台前排队(同步),在排队过程中做其他事情,比如玩手机,注意,玩手机的时候需要不时地去看是否已经排队排到了(非阻塞);
叫号排队,不用一直等在柜台前(异步),在排到前不做任何其他事情(阻塞);
叫号排队,不用一直等在柜台前(异步),在排到前做其他事情,比如玩手机,玩手机的时候不用关心是否排队排到了,因为会叫号通知(非阻塞);
通过去银行柜台办理业务的场景我们可以发现同步/异步、阻塞/非阻塞之间关注的点不一样,同步/异步关注的是消息如何通知,在上面那个场景里就是两种不同的通知方式:同步通知方式是由排队人一直等消息,异步通知方式是由叫号机发送消息来通知,排队人无需关注消息,这是同步/异步之间的主要区别。阻塞/非阻塞关注的是等待消息通知时的状态,阻塞的时候排队人的状态不变一直等着,非阻塞的时候可以变成其他非等待状态,如看手机,出去抽烟等。需要特别说明一下的是同步非阻塞这种状态,可以发现在做其他事情的时候需要不停的检查等待结果,所以这里存在一个任务切换引起的资源消耗问题。
现在我们来总结一下同步/异步、阻塞/非阻塞之间的区别:同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者。
相信看完上文你已经基本搞清楚同步/异步、阻塞/非阻塞的概念了,接下来我们通过一个生活实例来巩固复习一下,看看自己是否真的已经掌握。
平时大家都会上网下载一些东西,这里就假设我要下载一个视频,我们用这个场景再来复习一下同步/异步、阻塞/非阻塞的概念:
我通过看下载精度条等待下载完成的结果(同步),期间不做其他事情(阻塞)
我通过看下载精度条等待下载完成的结果(同步),期间去聊QQ,在聊QQ的时候不停地去看下载是否完成(非阻塞)
通过下载完成的提示音通知得到下载完成的结果(异步),期间不做其他事情(阻塞)
通过下载完成的提示音通知得到下载完成的结果(异步),期间去聊QQ,在聊QQ的时候不需要去看下载是否完成,因为下载完了提示音会通知我(非阻塞)
最后,需要注意理解的是“消息通知机制”和“等待消息通知时的状态”这两个概念,这是理解同步/异步、阻塞/非阻塞四个概念的关键所在。还有我们在讨论这四个概念的时候一定要放在同一个层级,比如操作系统级别,框架级别,业务代码级别等,因为一个事件在不同层级所属的性质不一定一样,只有在同一个层级,才能去讨论它的性质是同步/异步还是阻塞/非阻塞。