同步、异步、阻塞与非阻塞

同步与异步

首先来解释同步和异步的概念,这两个概念与消息的通知机制有关。也就是同步与异步主要是从消息通知机制角度来说的。

同步就是一个任务的完成需要依赖另外一个任务时,只有等待另外一个任务的完成后,这个任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

异步是不需要等待被另外一个任务的完成,只是通知另外一个任务要完成什么工作,然后自己这个任务接着往下执行,只要自己完成了我的任务就算完成了。至于另外一个任务最终是否真正完成,我这个任务无法确定,所以它是不可靠的任务序列。

消息通知

同步调用另外一个任务后,要一直等待返回消息(结果)通知后,才能进行后续的执行;
异步调用发出后,调用者不能立刻得到返回消息(结果),要通过状态、通知和回调来通知调用者

这里提到执行部件和调用者通过三种途径返回结果
状态、通知和回调。
使用哪一种通知机制,依赖于执行部件的实现

场景比喻

去银行办理业务

1.选择排队等候。
2.取一个小纸条上面有我的号码,等到排到我这号码时,由柜台的人通知我轮到我去办理业务了。
  • 排队等候:就是同步等待消息通知
  • 等待别人通知:就是异步等待消息通知

阻塞与非阻塞

阻塞和非阻塞这两个概念与程序(线程)
等待消息通知(无所谓同步或者异步)时的状态有关。
也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。

阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务.函数只有在得到结果之后才会返回。

非阻塞调用指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回.
表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加(后面比喻场景很强调),增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。

场景比喻

同步/异步关注的是消息通知的机制,而阻塞/非阻塞关注的是程序(线程)等待消息通知时的状态
例如小敏下载文件:

1.同步阻塞
小明一直盯着下载进度条,到 100% 的时候就完成。
说明同步:等待下载完成通知
说明阻塞:等待下载完成通知过程中,不能做其他任务处理

2.同步非阻塞
小明提交下载任务后就去打游戏,每过一段时间就去瞄一眼进度条,看到 100% 就完成。
说明同步:等待下载完成通知
说明非阻塞:等待下载完成通知过程中,去打游戏了,只是时不时会瞄一眼进度条
【小明必须要在两个任务间切换,关注下载进度】

3.异步阻塞
小明换了个有下载完成通知功能的软件,下载完成就“叮”一声。
不过小明仍然一直等待“叮”的声音(看起来就很傻)。
说明异步:下载完成“叮”一声通知
说明阻塞:等待下载完成“叮”一声通知过程中,不能做其他任务处理

4.异步非阻塞
仍然是那个会“叮”一声的下载软件,小明提交下载任务后就去干别的,听到“叮”的一声就知道完成了。
说明异步:下载完成“叮”一声通知;
说明非阻塞:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可
【软件处理下载任务,小明处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可】

综上所述
同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者,所以在异步机制中,处理消息者和触发机制之间就需要一个连接的桥梁

在银行的例子中,这个桥梁就是小纸条上面的号码。
在小明的例子中,这个桥梁就是软件“叮”的声音。

参考文章:https://www.jianshu.com/p/aed6067eeac9

你可能感兴趣的:(同步、异步、阻塞与非阻塞)