原文:

  1. 深入理解同步阻塞、同步非阻塞、异步阻塞、异步非阻塞_同步阻塞 同步非阻塞 异步阻塞 异步非阻塞-CSDN博客

#question 什么是同步?什么是异步?
#question 什么是阻塞 ?什么是非阻塞?

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

前面已经指出了关键性的知识点,下面将直接给本文四个概念的定义。为了更好的说明,笔者做了一张图,如下:

image-20240328104449646

对于主线程上执行的一系列函数,当其中的某个函数 A 需要与相关线程交互,而调用了另一个函数 a 时:

如果立即去执行函数 a,这称为同步。

如果没有去执行函数 a,而是将执行函数 a 的时机安排在未来的某个时间,然后马上继续执行函数 A,这称为异步。

当执行函数 a 时,直至获得完整的资源之前,都暂停执行当前函数,这称为阻塞。

当执行函数 a 时,立即获得瞬时的结果,然后马上继续执行当前函数。如果获得的瞬时资源不是完整的资源,之后周期性发送类似的请求,直至获得完整的资源,这称为非阻塞。

可以看出,同步与异步的区别在于函数调用的时机,而阻塞与非阻塞的区别在于发起请求后是否对本线程进行暂停。

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

很多读者(包含笔者)都喜欢作者能直截了当地给出概念,而反感拐弯抹角和旁敲侧击。因此,笔者再提炼一下本文的四个概念:

  1. 同步阻塞:在需要某资源时马上发起请求,并暂停本线程之后的程序,直至获得所需的资源。
  2. 同步非阻塞:在需要某资源时马上发起请求,且可以马上得到答复,然后继续执行之后的程序。但如果得到的不是完整的资源,之后将周期性地的请求,直至获得所需的资源。
  3. 异步阻塞:在需要某资源时不马上发起请求,而安排一个以后的时间再发起请求。当到了那时发出请求时,将暂停本线程之后的程序,直至获得所需的资源。在获取资源之后,使用共享信号量、异步回调等方式将结果异步反馈。
  4. 异步非阻塞:在需要某资源时不马上发起请求,而安排一个以后的时间再发起请求。当到了那时发出请求时,可以马上得到答复,然后继续执行之后的程序。但如果得到的不是完整的资源,之后将周期性地的请求。在最终获取到资源之后,使用共享信号量、异步回调等方式将结果异步反馈。

一个生动的例子

一个贴切生动的例子可能对理解更有帮助。这里假设了这样的一种情景:笔者正在进行公司安排的一个“cleancode”专项需求(下面简称 cleancode 专项),然后突然对于门禁上报告的一项告警不太理解,笔者想要求助自己的同事(设该同事名为 Bob),于是在公司的通信软件(设该软件名为 contact)上向其发送了此求助消息,并假设笔者每天有减脂的诉求,因此在下午下班后不会立刻去吃饭。

前述的四个概念类比如下:

同步阻塞:笔者在 contact 上给 Bob 发了一条咨询信息,并开启 contact 的消息自动弹出功能。然后笔者暂停手头的工作,翘着二郎腿开始用手机摸鱼,直到手机上弹出 contact 的关于 Bob 的回复信息。

解释:

笔者、笔者的同事 Bob:两个位于不同服务器上的操作系统。

cleancode 专项:正在“笔者操作系统”上运行的一个线程。

笔者放弃工作上的任务:cleancode 专项线程被阻塞。

笔者开始摸鱼:cleancode 专项线程因阻塞而使笔者空闲,笔者通过线程调度来运行其它无关线程。

contact 的消息自动弹出:在操作系统中,用于唤醒阻塞线程的信号量。

同步非阻塞:笔者在 contact 上给 Bob 发了一条咨询信息,然后笔者继续做 cleancode 专项中的其它内容,并周期性查看 Bob 有没有回复。

异步阻塞:笔者在日程表上记录了这个待办事项,然后笔者继续做 cleancode 专项中的其它内容,最后到下午下班时,笔者在 contact 上给 Bob 发了一条咨询信息,并开启 contact 的消息自动弹出功能。然后笔者暂停手头的工作,翘着二郎腿开始在晚上加班的时间用手机摸鱼,直到手机上弹出 contact 的关于 Bob 的回复信息。

异步非阻塞:笔者在日程表上记录了这个待办事项,然后笔者继续做 cleancode 专项中的其它内容,最后到下午下班时,笔者在 contact 上给 Bob 发了一条咨询信息,然后笔者继续加班做 cleancode 专项中的其它内容,并周期性查看 Bob 有没有回复。

异步阻塞相对于同步阻塞的意义是什么

前面已作说明,同步阻塞与异步阻塞的区别只在于执行时机不同。既然同步阻塞与异步阻塞函数都只使用一个线程,那异步阻塞相对于同步阻塞的意义是什么?为什么要使用异步阻塞?

首先,从运筹学的角度来说,合理的安排任务的执行时机是可以提高效率的,读者通过生活经验就可以判断出来。