初次接触这2组概念时候,很容易犯糊涂,觉得意思很相近,感觉同步和阻塞差不多,都是一个做不完,一直等,直到完成再去处理其他事,异步和非阻塞都是无需等待的分别完成一些操作。真的是这样吗?
一、概念上理解
1. 同步和异步只要针对客户端(C端)
同步,就是在客户端发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事。
例子:普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事。
异步,当c端一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
例子:ajax请求(异步): 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
2. 阻塞和非阻塞针对的是服务端(S端)
阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。
例子:比如到你某个时候到A楼一层(假如是内核缓冲区)取快递,但是你不知道快递什么时候过来,你又不能干别的事,只能死等着。但你可以睡觉(进程处于休眠状态),因为你知道快递把货送来时一定会给你打个电话(假定一定能叫醒你)。
非阻塞指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
例子:还是取快递,如果用忙轮询的方法,每隔5分钟到A楼一层(内核缓冲区)去看快递来了没有。如果没来,立即返回。而快递来了,就放在A楼一层,等你去取。
二、老王烧水的例子
网上流传的一个经典的老王烧水的故事(网友真TM有才):
出场人物:老王,水壶两把(普通水壶,简称水壶;烧开后会响的水壶,简称响水壶)。
老王想了想,有好几种等待方式:
- 老王用水壶烧水,并且站在那里,不管水开没开,每隔一定时间看看水开了没。——同步阻塞
老王想了想,这种方法不够聪明。
- 老王还是用水壶烧水,不再傻傻的站在那里看水开,跑去卧室上网,但是还是会每隔一段时间过来看看水开了没有,水没有开就走人。——同步非阻塞(轮询)
老王想了想,现在的方法聪明了些,但是还是不够好。
- 老王这次使用高大上的响水壶来烧水,还是站在那里,但是不会再每隔一段时间去看水开,而是等水开了,水壶会自动的通知他。——异步阻塞
老王想了想,既然水壶可以通知我,那我为什么还要傻傻的站在那里等呢,嗯,得换个方法。
- 老王还是使用响水壶烧水,跑到卧室上网去,等着响水壶自己把水烧开了以后通知他。——异步非阻塞
老王豁然,这下感觉轻松了很多。
同步和异步
同步就是烧开水,需要自己去轮询(每隔一段时间去看看水开了没),异步就是水开了,然后水壶会通知你水已经开了,你可以回来处理这些开水了。
同步和异步是相对于操作结果来说,会不会等待结果返回。
阻塞和非阻塞
阻塞就是说在烧水的过程中,你不可以去干其他的事情,非阻塞就是在同样的情况下,可以同时去干其他的事情。阻塞和非阻塞是相对于线程是否被阻塞。
三、总结
-
同步,就是我客户端(c端调用者)调用一个功能,该功能没有结束前,我(c端调用者)死等结果。
-
异步,就是我(c端调用者)调用一个功能,不需要知道该功能结果,该功能有结果后通知我(c端调用者)即回调通知。
-
阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)没有接收完数据或者没有得到结果之前,我不会返回。
-
非阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)立即返回,通过select通知调用者。
同步/异步主要针对C端, 但是跟S端不是完全没有关系,同步/异步机制必须S端配合才能实现.同步/异步是由c端自己控制,但是S端是否阻塞/非阻塞, C端完全不需要关心。
网友评论