那些年搞不懂的多线程、同步异步及阻塞和非阻塞(二)---概念区分
概念解释:
同步/异步, 它们是消息的通知机制
同步:
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。
简单来说就是当前程序执行完才能执行后面的程序,程序执行时按照顺序执行,平时写的代码基本都是同步的;
异步:
异步的概念和同步相对。
当一个异步过程调用发出后,调用者不会立刻得到结果。实际处理这个调用的部件是在调用发出后,通过状态、通知来通知调用者,或通过回调函数处理这个调用。
简单来说就是程序没有等到上一步程序执行完才执行下一步,而是直接往下执行,前提是下面的程序没有用到异步操作的值,异步的实现方式基本上都是多线程(定时任务也可实现,但是情况少)。
阻塞/非阻塞, 它们是程序在等待消息(无所谓同步或者异步)时的状态.
阻塞:
阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。
对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
非阻塞:
非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
简单示例:老张烧水
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)(本可以坐着等通知的却非要立即等着,实际不大会出现这种情况,异步异步阻塞没有实际意义)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
所谓同步异步,只是对于水壶而言。
普通水壶,同步;响水壶,异步。
虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。
立等的老张,阻塞;看电视的老张,非阻塞。
情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
同步阻塞关系:
线程阻塞(祥见多线程介绍)除了程序主动调用休眠外常见的就是程序遇到同步代码块,同一时间不能并行执行,当有多个请求了出现线程等待的情况即为阻塞。
同步原因:
阻塞源于同步代码块,首先需要弄清楚何时需要同步,需要同步的地方是因为多个线程操作了同一个变量,导致在并行执行时变量值的混乱,故需要加同步锁来实现同一时间只能有同一个线程执行同步代码块中的程序,如果不涉及多线程操作同一个变量的情况是不需要使用同步的,在多线程编程时尽量避免操作公共变量来避免阻塞。