同步异步阻塞和非阻塞的区别理解

一、同步和异步

同步异步是一种 消息通知机制

  • 同步:发出一次请求后必须等到该请求有返回结果,才能继续下一步工作;请求者需主动询问是否有返回结果;
  • 异步:发出一次请求后无需等到该请求有返回结果,即可进行下一步工作;请求有结果后,会以某种方式通知请求者;

同步和异步是相对于操作结果来说,会不会等待结果返回

异步一般通过状态、通知和回调来通知调用者。
状态:即监听被调用者的状态(轮询),调用者需要每隔一定时间检查一次,效率会很低。
通知:当被调用者执行完成后,发出通知告知调用者,无需消耗太多性能。
回调:与通知类似,当被调用者执行完成后,会调用调用者提供的回调函数。

场景比喻:
举个例子,去银行办理业务,可能会有两种方式:排队等候和排号等别人通知

  • 前者(排队等候)就是同步等待消息通知,也就是我要一直在等待银行办理业务情况;
  • 后者(排号,等待别人通知)就是异步等待消息通知。在异步消息处理中,等待消息通知者(在这个例子中就是等待办理业务的人)往往注册一个回调机制,在所等待的事件被触发时由触发机制(在这里是柜台的人)通过某种机制(在这里是写在小纸条上的号码,喊号)找到等待该事件的人。

二、阻塞和非阻塞

阻塞、非阻塞,是程序等待调用结果时的状态

  • 阻塞:发出一次请求后,在未得到返回结果前,线程挂起,这期间线程无法做其他事情;
  • 非阻塞:发出一次请求后,在未得到返回结果前,线程不会挂起,这期间线程可以做其他事情;

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

场景比喻:

  • 阻塞。继续上面的那个例子,不论是排队还是使用号码等待通知,如果在这个等待的过程中,等待者除了等待消息通知之外不能做其它的事情,那么该机制就是阻塞的,表现在程序中,也就是该程序一直阻塞在该函数调用处不能继续往下执行。

  • 非阻塞。相反,有的人喜欢在银行办理这些业务的时候一边打打电话发发短信一边等待,这样的状态就是非阻塞的,因为他(等待者)没有阻塞在这个消息通知上,而是一边做自己的事情一边等待。

同步异步阻塞非阻塞总结:

  • 同步机制 发送方发送请求之后,需要等接收方发回响应后才接着发
  • 异步机制 发送方发送一个请求之后不等待接收方响应这个请求,就继续发送下个请求。
  • 阻塞调用调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回,该线程在此过程中不能进行其他处理
  • 非阻塞调用调用结果不能马上返回,当前线程也不会被挂起,而是立即返回执行下一个调用。(网络通信中主要指的是网络套接字Socket的阻塞和非阻塞方式,而soket 的实质也就是IO操作)

区分开同步异步阻塞非阻塞,同步异步说的是被调用者结果返回时通知进程的一种通知机制,阻塞非阻塞说的是调用结果返回前进程的状态,是挂起还是继续处理其他任务。

三、同步异步阻塞非阻塞组合应用

  • 同步阻塞方式: 发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。这种方式实现简单,但是效率最低

  • 同步非阻塞方式:发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就立即返回,去做其他事情,但由于没有得到请求处理结果,不响应发送方,发送方一直等待。一直到IO操作完成后,接收方获得结果响应发送方后,接收方才进入下一次请求过程。在实际中不使用这种方式。

  • 异步阻塞方式:发送方向接收方发送请求后,不用等待响应,可以接着进行其他工作;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。这种方式在实际中也不使用。

  • 异步非阻塞方式:发送方向接收方请求后,不等待响应,可以继续其他工作,接收方处理请求时进行IO操作如果不能马上得到结果,也不等待,而是马上返回取做其他事情。当IO操作完成以后,将完成状态和结果通知接收方,接收方在响应发送方。效率最高

场景比喻:

对上面所讲的概念再次进行一个场景梳理,上面已经明确说明,同步/异步关注的是消息通知的机制,而阻塞/非阻塞关注的是程序(线程)等待消息通知时的状态。以小明下载文件打个比方,从这两个关注点来再次说明这两组概念,希望能够更好的促进大家的理解。

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

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

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

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

也就是说,同步/异步是“下载完成消息”通知的方式(机制),而阻塞/非阻塞则是在等待“下载完成消息”通知过程中的状态(能不能干其他任务),在不同的场景下,同步/异步、阻塞/非阻塞的四种组合都有应用。

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

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

最后,请大家注意理解“消息通知机制”和“等待消息通知时的状态”这两个概念,这是理解四个概念的关键所在。

参考:https://www.jianshu.com/p/252a522517f9

四、其它理解

原文链接:https://blog.csdn.net/linhuaiyang/article/details/68483222
网上找了一篇总结的很简洁清晰,已粘贴原文内容如下:

同步、异步:
  • 概念:消息的通知机制
  • 解释:涉及到IO通知机制;所谓同步,就是发起调用后,被调用者处理消息,必须等处理完才直接返回结果,没处理完之前是不返回的,调用者主动等待结果;所谓异步,就是发起调用后,被调用者直接返回,但是并没有返回结果,等处理完消息后,通过状态、通知或者回调函数来通知调用者,调用者被动接收结果。
阻塞、非阻塞:
  • 概念:程序等待调用结果时的状态
  • 解释:涉及到CPU线程调度;所谓阻塞,就是调用结果返回之前,该执行线程会被挂起,不释放CPU执行权,线程不能做其它事情,只能等待,只有等到调用结果返回了,才能接着往下执行;所谓非阻塞,就是在没有获取调用结果时,不是一直等待,线程可以往下执行,如果是同步的,通过轮询的方式检查有没有调用结果返回,如果是异步的,会通知回调。

经典故事案例:

  • 人物:老张
  • 道具:普通水壶(水烧开不响);响水壶(水烧开发出响声)
  • 案例
 1、同步阻塞:
       老张在厨房用普通水壶烧水,一直在厨房等着(阻塞),盯到水烧开(同步);
 2、异步阻塞:
       老张在厨房用响水壶烧水,一直在厨房中等着(阻塞),直到水壶发出响声(异步),老张知道水烧开了;
 3、同步非阻塞:
       老张在厨房用普通水壶烧水,在烧水过程中,就到客厅去看电视(非阻塞),然后时不时去厨房看看水烧开了没(轮询检查同步结果);
 4、异步非阻塞:
       老张在厨房用响水壶烧水,在烧水过程中,就到客厅去看电视(非阻塞),当水壶发出响声(异步),老张就知道 水烧开了。

你可能感兴趣的:(计算机网络)