前言
在最近的一些面试中,跟应聘者聊了比较多关于“同步/异步,阻塞/非阻塞”相关的话题,发现大家对于这些概念的理解都比较模糊,甚至有的同学会反问“他们不就是同一个东西吗?”。所以借着这么一个机会,我想用一些尽量简单的例子,尽量简洁的语言来聊聊自己对于这些概念的看法。
正文
这篇文章想通过一个老王“候车”的案例来解释这些概念。
同步阻塞
放假了,老王回到了乡下,由于乡下的基础设施比较差,当他在车站候车的时候,只能一直在干等着,直到公交车的到站。
这时候对于公交车(被调用着者)来说,它是“同步“的。老王(调用者)被公交车(被调用者)“阻塞”在站台上。
异步阻塞
放完假了,老王回到了大城市开始上班,同样在车站候车,一样在车站干等着,但是大城市的基础设施建设得比较好,当公交车到站的时候,会有广播提示提醒乘客。
那么这时候对于公交车(被调用着者)来说,它是“异步“的,到站后会通知调用者。但是此时老王(调用者)还是被公交车(被调用者)“阻塞”在站台上。
同步非阻塞
过年了,老王放假回来了乡下,又要开始候车了,这时候他变聪明了,没有一直在车站上干等着,而是去找隔壁的小花叙叙旧。但是又害怕车到站了自己会错过,就只能隔一段时间过来看看车到了没。
那么这时候对于公交车(被调用着者)来说,它是“同步“的。但是此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的。
异步非阻塞
改革春风吹满地,新农村建设正在火热进行中,此时的乡下,公交车里面也安装了车辆到站的提醒广播。现在老王在候车的时候,可以安心的跟小花叙旧了,当听到自己需要乘坐的车辆到站广播时,才过去车站上车。
这时候对于二手交易平台(被调用着)来说,它是“异步“的,到站后会广播提醒,此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的
概念总结
从上面的示例中,我们可以明白一件事情,同步异步,阻塞非阻塞他们针对的对象是不一样的。对于调用者来说是阻塞跟非阻塞,被调用者是同步跟异步。
同步:A调用B,此时只有等B有结果了才返回。
异步: A调用B,B立即返回,无须等待。当B处理完之后会通过通知或者回调函数的方式来告诉A结果。
阻塞:A调用B,A会被被挂起,一直在等待B的结果,什么事都不能干。
非阻塞:A调用B,自己用被挂起等待B的结果,可以去干其他的事情。
Java中相关概念
在Java中的IO模型有三种,分别是BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO(异步非阻塞IO)。这时候我们会发现,异步阻塞的模型是不存在的。
NIO跟AIO的出现解决了很多在BIO使用过程遇到的难题,所以我们在选择使用何种IO的时候需要根据业务场景来做决定,没必要一味追求NIO跟AIO,不仅加大了编码的难度也提高的出错的概率,技术的出现是为了更好的解决问题。