工作了有一段时间了,但是今天看到这个问题时自己先想了想,大概能明白同步和异步的区别,但是阻塞和非阻塞就想不清楚了,后来网上查阅了好多资料,甚至好多资料里边的解释都是不一样的,下面我用用我能理解的最简单的语言给大家解释一下这些区别,仅供参考,如有不同意见,欢迎砸砖。
同步和异步:
同步和异步是在线程层次来说的,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者,同步和异步最大的区别就在于。一个需要等待,一个不需要等待。
比如广播,就是一个异步例子。发起者不关心接收者的状态。不需要等待接收者的返回信息
电话,就是一个同步例子。发起者需要等待接收者,接通电话后,通信才开始。需要等待接收者的返回信息
同步:发送一个请求,等待返回,然后再发送下一个请求
异步:发送一个请求,不等待返回,随时可以再发送下一个请求
从图中可以看出同步是发送一个消息,返回一个消息,在这之间不会做别的事,需要等待只是在等待消息返回,几次发送消息是有顺序的,这是一种可靠的任务序列。要么成功都成功,失败都失败。而异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
同步可以避免出现死锁,读脏数据的发生,一般共享某一资源的时候用,如果每个人都有修改权限,同时修改一个文件,有可能使一个人读取另一个人已经删除的内容,就会出错,同步就会按顺序来修改。
异步则是可以提高效率了,现在cpu都是双核,四核,异步处理的话可以同时做多项工作,当然必须保证是可以并发处理的。
这些都是对的。
下面来看网上的一个解释:
同步和异步关注的是消息通信机制(synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。
而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。
典型的异步编程模型比如Node.js
举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。
阻塞和非阻塞
阻塞与非阻塞主要是从 CPU 的消耗上来说的,阻塞和非阻塞应该是发生在消息的处理的时刻。阻塞其实就是等待,发出通知,等待结果完成。非阻塞属于发出通知,立即返回结果,没有等待过程。
阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事,等这个慢的操作完成时,CPU 再接着完成后续的操作。虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估。
打个比喻吧:司机开车在路上阻车了,如果采用阻塞模式,则司机停下来什么事也不干,就眼巴巴地直等前面的车启动,他继续跟车。如果采用非阻塞模式,则前面阻车后,司机停下来看报纸,听音乐,等前面车走动后,他再放下报纸,继续跟车。
总结:
同步异步是在线程层次来说的,阻塞非阻塞是在cpu层次来说的,层次不同
同步与异步:是自己去做这件事情,自己拿结果(同步),还是等别人做好了来通知有结果(异步),注意这里说的是拿结果。通常异步效率比较高,因为不用等待,同步效率比较低,要等待。同步:发送一个请求,等待返回,然后再发送下一个请求,异步:发送一个请求,不等待返回,随时可以再发送下一个请求
阻塞非阻塞区别在于完成一件事情时,当事情还没有完成时,处理这件事情的人除此之外还能不能再做别的事情;能的话就是非阻塞,不能就是阻塞。
转