什么是异步

引文

我们从这样一个故事开始。某天午饭时间,大家聊得正嗨。

小A突然来了一句:“我X,这傻缺网站支付太慢了,等圈圈转了半天。最后告诉我连接银行接口支付失败,你不能做成异步啊。先告诉我成功,有支付结果再通知我,害的我等了半天”。
新来的同事小B弱弱的问了句:“哥,什么是异步啊?”
前端小C:“异步就是回调。”
小A补充说:“异步就是多线程。”
小C似懂非懂地看着我。
我啃了一口鸡腿:“嗯,他俩说的都对,又都不对。如果安卓的小D在,他可能会说异步不就是事件监听嘛。”
瞬间三人同时盯着我,说的好像很高深,你给解释解释啊。

其实要想理解什么是异步,很简单。凡是要用辩证的眼光要看待。我们先来看看什么是同步。

同步

同步是指用户在进行某个操作之后,暂停下一步操作,直到本次操作结束返回,期间持有的资源也一直占用。

举个栗子:

很久以前,还没有手机的时候。老一辈处对象,想聊聊天只能打电话,每次一打就是几个小时。期间只能对着电话你一句,我一句地呱啦呱啦说一通,啥也不能干。
我们聚焦在聊天这件事上,通过电话来聊天就是一个同步事件,聊天的双方,你一言我一语,交替进行。从一方一看,我说一句,必须等对方应答,我才能说下一句。这里电话就是竞争的资源,一个使用,其他人就不能使用。

异步

接下来,异步概念闪亮登场。什么是异步?异步可以理解为同步的对立面。

我们来想一下,有什么样的方式让两人之间可以不用你一言,我一语地等待,同时不依赖于仅有的电话资源呢。
你可能想到了写信。是的,在那个年代的确是通过写信来解决的。以当时的物价来衡量的化,打电话还是很昂贵的。所以自然而然的就可以通过写信来解决。
通过写信的方式 ,两个人不必等待。我可以把我想对你说的话一股脑全部写到信里。然后偷到邮箱,剩下的就是满心欢喜的期待,等待你的回信。
等待的时间里我可以学学三弦,拉拉京胡,京剧走起。既丰富了生活,又陶冶了情操。如果十天半月收不到回信,我就再写一封。貌似生活野蛮惬意的。
和上面的同步相比,这就是异步。

小B觉得更懵了,这不就是说写信比打电话更适合,异步比同步好吗?那我们是不是在倒退啊。
回到我们之前的观点,凡事看问题,都要从两面性出发。同步和异步的使用也是分场景的,不同的业务场景使用不同的技术。
譬如,在实时性要求比较高的场景下,譬如数据库操作,我们需要使用同步。
再举个例子:

现在你和女朋友闹别扭,你俩都要掰了,要黄了,你还在写信,慢慢腾腾的。等她收到信,估计你是没希望了。这时候,你可定不计较金钱、时间,终极目标就是在最短时间内挽回这段美好的爱情。
相比而言,使用写信的方式,更经济,占用的资源少,双方也有更大的自有,不必完全拘泥于这件事,专业术语来讲叫强耦合,强关联,但是等到对方的回应很慢,有时候邮差把新建弄丢了,可能这辈子都收不到这份回信。而打电话,更直接,相对而言花销大,双方只能一直捧着电话叽叽歪歪,但是可以立马获得对方的甜言蜜语。
那是不是异步一定就比同步的慢呢?还是那句话,要看具体的业务场景,以及具体使用的技术而定而定。譬如在上述的异步情况下,我们可以使用微信语音。同样是异步,但是速度却可以接近近实时。
我们简单总结一下,同步需要等待结果返回,会相对占用资源。异步可以先于真实的结果返回,不需要等待,操作完车后释放资源,不占用竞争资源。

# 异步的使用场景:
那在什么情况下我们需要使用异步呢?

1.任务执行可以不按顺序,即没有特定的时序性或顺序性;
2.操作需要耗费资源,譬如I/O操作,网络请求;
3.不存在共享资源的互斥访问;
4.对于实时性要求不是很高;
5.对核心任务影响不大;
5.非原子性操作;
6.非强一致性操作

异步的好处

那么使用异步有什么好处呢?

可以并发或并行执行非顺序性任务,提高执行效率;
节省资源,业务低耦合,获取更好的用户体验;
避免资源的竞争访问,避免阻塞,避免死锁;
延迟返回,提高请求的响应率

异步的实现

好了,最后我们回到最初问题的讨论,我们来看看大家关于问题的讨论。

 小C:“异步就是回调。”
 小A:“异步就是多线程。”

在我们理解了什么是异步之后我们会发现,他俩说的都对,前端的回调,或是多线程,以及事件监听,都是异步编程的提现,都能实现一定程度的异步。
但是异步并不止于此,他更多的是一种思想。上述只是他在不同语言,不同业务场景的落地。
其实他还有更多的实现。

我们从一个大的宏观的角度来看,从服务、系统的层面,每一个服务都是一个异步编程提现,譬如微服务体系中的每一服务;
我们从具体服务的架构上来看也是存在异步的,譬如我们常使用的各种中间件,消息队列MQ,
我们通过MQ将生产者和消费者相互隔离开,生产者只关心生产,消费者只关心消费;
我们再从具体的业务实现来看也是有异步的,譬如使用的业务回调,注册推送等;
再比如实现的各种语言也都有不同的异步实现,譬如C的pthread,java的多线程,python的threading,async/wait,golang的gorutine等等。
还有各种编程框架,netty,Akka,flask,C语言的libUV库等等;
甚至经典的操作系统I/O多路复用模型select,poll,epoll等等。

异步可以说无处不在。
听了我的话,他们三人若有所思的点点头。最后我要说的是,异步更重要的是一种思想,而不是特定的实现。

重新开更

自从博客的阿里云到期后,已经好久没更新了。突然想到了胡适先生的笔记:

《胡适留学日记》卷一(有关“打牌”记录全在这一卷)中有“打牌”记录累计36次(二月1次、三月1次、四月3次、五月3次、六月3次、七月11次、八月10次、九月4次),从1911年2月5日至9月6日(次日虽提及“打牌”但实未打牌,且算作1次)戒牌为止,平均6天打牌一次。在最频繁的七、八、九月,平均不到三天就打牌一次,真可谓三天两头打。

胡适记打牌之事,一般仅“打牌”两个字而已。有时会多些几个字,但似乎有为“打牌”之行为开脱之嫌。如:
2月5日,“刘千里以电话邀打牌。”【友人相邀,面子不可拂却。】
4月29日,“天时骤暖至八十度以上,不能读书,与沈、陈诸君打纸牌,又与刘、侯诸君打中国牌,以为消遣之计。”【天热好打牌。】
5月14日,“夜与刘千里诸人打牌。刘君已毕业,云下星期二将归祖国矣。”【大概打牌也算是为友人“饯行”的一种方式吧】
7月2日,“天热不能作事,打牌消遣。”【天又热了。】
7月3日,“今日天气百一十度。打牌。”【八十度就只能去打牌了,一百一十度就更甭说了。】
7月8日,“无事。打牌。天气稍凉矣。”【今天打牌不是因为天热,纯属无事闹的。】
8月4日,“化学第四小考,极不称意;平生考试,此为最下。打牌。”【因为考试成绩不称意,所以打牌以消遣。可是成绩不好,又是为什么呢?查7月17日“化学试卷竟得百分,直出意料。”同一门课,不到一个月,成绩落差如斯,谁之罪耶?打牌也。】
8月5日,“打牌。”【全天记录仅次两字,显然对昨日化学考试之成绩仍耿耿于怀。】
8月10日,“夜早睡;连日或以读书,或以打牌,恒子夜始寝,今日觉有不适,故以此矫之。”【打牌的代价不仅仅是化学成绩下降那么简单哈。】
9月4日,“今日为劳动节(Labor Day),为休息之日。打牌。”【劳动节,要休息,所以打牌,最冠冕堂皇的理由了。】

大概是觉察到了自己的堕落,胡适于是要洗心革面了。在9月6日的日记里写道,“今日,迁居世界学生会所,初次离群索居,殊觉凄冷。昨日,与金涛君相戒不复打牌。”自此日起,(留学)日记中不复出现“打牌”矣。

这样下去,我不就是先生日记里写的吗。想想买域名,买阿里云服务器花费的,那可都是白花花的银子啊。新学期,新气象,从今天起要继续开更,记录学习过程。