关于同步异步与阻塞非阻塞与的理解

最近聊到一个关于同步异步 阻塞非阻塞 理解的问题。我们以下面这个例子大概的说一下关于这个问题的理解。


我平时比较喜欢喝粥,那就拿煮粥举个例子吧,煮粥有几种方式如下:

方式一:我将洗好的米放到电饭煲里,并且一直站在那里,每隔一段时间就看下粥煮好没。——同步阻塞

  • 同步体现在:每隔一段时间就看下粥煮好没。
  • 阻塞体现在:等待粥煮的过程中,一直站在那里,不能做其他事情。

方式二:我将洗好的米放到电饭煲里,这次不在一直站在那里,而是炒个西红柿鸡蛋,但是还是会每隔一段时间过去看下粥煮好没。——同步非阻塞

  • 同步体现在:每隔一段时间就看下粥煮好没。
  • 非阻塞体现在:等待粥煮的过程中,去炒了个西红柿鸡蛋,只是时不时会看下粥煮好没。

为提高生活的幸福感,家里电饭煲升级换代,在双十一买了一款支持WiFi的智能电饭。

方式三:同样,我将洗好的米放到电饭煲里,电饭煲提示"开始煮粥" ,我一直站在那里,但是不会再每隔一段时间去看粥煮好了没,粥煮好后电饭煲会通过手机铃声自动的通知我。——异步阻塞

  • 异步体现在:提示"开始煮粥"后,不需要去看,粥煮好后,电饭煲会自动通知我。
  • 阻塞体现在:等待粥煮的过程中,一直站在那里,不能做其他事情;

方式四:再次煮粥的时候,我想了想,既然电饭煲会自动通过手机通知我,我还站在那里干嘛,于是我不在傻傻的等着,而是去炒个西红柿鸡蛋,粥煮好电饭煲后自动通知我。——异步非阻塞

  • 异步体现在:提示"开始煮粥"后,不需要去看,粥煮好后,电饭煲自动通知我。
  • 非阻塞体现在:等待电饭煲自动通知我的过程中,去炒了个西红柿鸡蛋,只需要接收电饭煲通知即可。

通过上面这个例子,我们可以看到同步/异步关注的是“煮粥完成消息”通知的方式(消息通知机制),而阻塞/非阻塞关注的是等待“煮粥完成消息”通知过程中的状态(是否做其他任务)

总结一下

同步异步 主要是从消息通知机制角度来说的,涉及IO通知机制。同步指的是发起调用后,被调用者处理消息,没处理完之前,调用者需要不断轮询数据是否处理完成,或者一直在等待处理完成,必须等处理完才直接返回结果,调用者在主动等待结果。而异步指的是发起调用后,被调用者直接返回,但并没有返回结果,等处理完消息后,通过状态或回调函数等形式来通知调用者,调用者被动接收结果。(由此看来,似乎同步的实时性比较好,异步的并发性能比较好)

阻塞非阻塞 主要是从程序(线程)等待消息通知时的状态角度来说的,涉及CPU线程调度。阻塞指的是调用结果返回之前,该执行线程会被挂起,线程不能做其它事情,只能等待,只有等到调用结果返回了,才能继续往下执行。非阻塞指的是在没有获取调用结果时,不是一直等待,线程可以继续往下执行,做其他事情,此时如果是同步的,通过轮询的方式检查有没有调用结果返回,如果是异步的,会通知回调。

同步异步与阻塞非阻塞它们修饰的对象不一样,阻塞非阻塞,是指进程需要的数据如果未就绪,需不需要等待; 同步异步,是指数据准备好后进行访问的机制,访问数据的时候,需不需要等待IO处理完成,同步需要等待IO完成,异步是IO完成后通知进程进行处理。