What's Concurrency? The Magic of Doing Lots of Things at Once!
你上周三是不是就遇到过这种事?那天下午第一节课是体育课,操场边的冰淇淋车突然开进来,卖限量的“恐龙蛋”甜筒——就是甜筒上插了个恐龙造型的巧克力,全年级只有200个,先到先得。下课铃一响,“嘭”的一声,整个操场的人跟小蚂蚁搬家似的往冰淇淋车冲,你跑得最快,抢到了第187个位置,前面还有186个小朋友。你踮着脚数了数,只有一个穿蓝条纹围裙的叔叔当收银员,他一次只能接一个小朋友的钱、打一个甜筒、找零钱,前面那个穿篮球服的小胖子,掏了皱巴巴的5块钱,叔叔收了钱,慢悠悠打了30秒甜筒,找他2块钱,他才蹦蹦跳跳走开。你算了算,前面186个小朋友,每个至少花30秒,你至少要等93分钟——整整一节课半的时间!等你拿到甜筒,都要上课了,而且恐龙蛋巧克力说不定都化成了一滩。你垂头丧气地排在队伍里,恨不得自己有分身术,能同时帮所有小朋友打甜筒,这样大家都不用等了。

这种“一次只处理一件事,处理完下一件”的方式,就叫串行处理(Sequential Processing)。就像你走学校的独木桥,一次只能过一个人,前面的人没走完,后面的人只能等着,哪怕你跑得再快,也只能排在后面慢慢挪。串行的好处是特别“稳”,不会出错——叔叔一次只接一个小朋友的钱,不会找错零,也不会把甜筒给错人,但是坏处就是特别慢,人一多就挤爆了。要是用串行的方式给全校2000个小朋友发甜筒,最后一个小朋友要等整整4个小时,等到太阳都下山了,冰淇淋车都收摊了。
那如果变成并发(Concurrency)会怎么样?你眼巴巴看着冰淇淋车,要是突然冒出5个穿同样蓝条纹围裙的叔叔,每个人负责一个收银台,同时打甜筒,500个小朋友只要排成5队,每队100个,每个人最多等50分钟,比之前快了一倍!如果有10个叔叔,就只要等25分钟,快的时候还能赶上最后一节课。这种“很多件事同时发生,同时处理”的方式,就是我们今天要讲的——并发,就是“同时做很多事”,能让慢吞吞的串行处理一下子变快,能服务更多的人,做更多的事。
---
你的早上,其实全是并发
你不用觉得并发是什么电脑里才有的高深概念,你每天早上起床,已经在用并发了! 假设你早上7点起床,要是用串行的方式做事:先花5分钟穿衣服,再花5分钟刷牙洗脸,再花10分钟吃妈妈热的早餐,再花3分钟收拾书包检查作业,最后花2分钟穿鞋拿钥匙出门,总共要花25分钟。要是你7点10分才起床,肯定要迟到,被老师罚站在门口。
但如果你用并发的方式做:
- 你穿衣服的5分钟里,妈妈刚好帮你热好早餐,两件事同时做,省了5分钟;
- 你去卫生间刷牙洗脸的5分钟里,你顺便把书包收拾好,检查了数学作业有没有带,又省了3分钟;
- 你等早餐热好的2分钟里,你已经穿好鞋拿好钥匙了,又省了2分钟;
- 最后你坐下来吃早餐的10分钟里,还能顺便听两首你喜欢的歌,最后总共只要12分钟!比串行快了13分钟,多睡13分钟它不香吗?省下来的时间你还能在楼下多玩5分钟滑滑梯,或者多看两页你喜欢的漫画书。
你看,并发根本不是什么难事,就是“同时做两件不冲突的事”,省下来的时间都是你自己的!

---
并发的小麻烦:同时做很多事,很容易乱
但是并发也不是万能的,就像你一边吃早餐一边看动画片,是不是很容易把牛奶洒在衣服上?或者一边写作业一边玩橡皮,是不是半小时的作业写了一小时?并发最大的问题就是:当很多事同时发生的时候,如果没有规则,很容易乱成一锅粥。
我们再回到冰淇淋店的例子:如果有两个收银员,但是只有一个甜筒机,两个叔叔同时给小朋友打甜筒,是不是会出现“甜筒做好了,两个叔叔同时伸手拿,结果甜筒‘啪’的一声掉在地上”的情况?或者两个小朋友同时抢最后一个恐龙蛋甜筒,是不是会推推搡搡,甚至吵架?再比如你和弟弟一起分生日蛋糕,蛋糕上有10颗新鲜的草莓,你们俩同时伸手去抓最大的那颗,“哗啦”一声,蛋糕盘子翻了,奶油蹭了你们俩一身,草莓咕噜噜滚到桌子底下,最后谁都没吃到,是不是特别倒霉?

这种“一次只处理一件事,处理完下一件”的方式,就叫串行处理(Sequential Processing)。就像你走学校的独木桥,一次只能过一个人,前面的人没走完,后面的人只能等着,哪怕你跑得再快,也只能排在后面慢慢挪。串行的好处是特别“稳”,不会出错——叔叔一次只接一个小朋友的钱,不会找错零,也不会把甜筒给错人,但是坏处就是特别慢,人一多就挤爆了。要是用串行的方式给全校2000个小朋友发甜筒,最后一个小朋友要等整整4个小时,等到太阳都下山了,冰淇淋车都收摊了。
那如果变成并发(Concurrency)会怎么样?你眼巴巴看着冰淇淋车,要是突然冒出5个穿同样蓝条纹围裙的叔叔,每个人负责一个收银台,同时打甜筒,500个小朋友只要排成5队,每队100个,每个人最多等50分钟,比之前快了一倍!如果有10个叔叔,就只要等25分钟,快的时候还能赶上最后一节课。这种“很多件事同时发生,同时处理”的方式,就是我们今天要讲的——并发,就是“同时做很多事”,能让慢吞吞的串行处理一下子变快,能服务更多的人,做更多的事。
---
你的早上,其实全是并发
你不用觉得并发是什么电脑里才有的高深概念,你每天早上起床,已经在用并发了! 假设你早上7点起床,要是用串行的方式做事:先花5分钟穿衣服,再花5分钟刷牙洗脸,再花10分钟吃妈妈热的早餐,再花3分钟收拾书包检查作业,最后花2分钟穿鞋拿钥匙出门,总共要花25分钟。要是你7点10分才起床,肯定要迟到,被老师罚站在门口。
但如果你用并发的方式做:
- 你穿衣服的5分钟里,妈妈刚好帮你热好早餐,两件事同时做,省了5分钟;
- 你去卫生间刷牙洗脸的5分钟里,你顺便把书包收拾好,检查了数学作业有没有带,又省了3分钟;
- 你等早餐热好的2分钟里,你已经穿好鞋拿好钥匙了,又省了2分钟;
- 最后你坐下来吃早餐的10分钟里,还能顺便听两首你喜欢的歌,最后总共只要12分钟!比串行快了13分钟,多睡13分钟它不香吗?省下来的时间你还能在楼下多玩5分钟滑滑梯,或者多看两页你喜欢的漫画书。
你看,并发根本不是什么难事,就是“同时做两件不冲突的事”,省下来的时间都是你自己的!甚至你一个人在家的时候,也能玩并发:比如周末妈妈出门买菜,给你布置了三个任务:把脏衣服放进洗衣机、写20道数学题、等烤箱里的巧克力饼干烤好。你要是串行做:先放衣服(2分钟),再写数学题(15分钟),再等饼干(10分钟),总共要27分钟。但你要是用并发:放衣服的2分钟里,你顺便把数学题的前5道做了,等饼干烤的10分钟里,你把剩下的15道题全写完,最后总共只要12分钟!省下来的15分钟,你还能看一集你喜欢的动画片,或者下楼玩10分钟滑板,是不是特别爽?

---
并发的小麻烦:同时做很多事,很容易乱
但是并发也不是万能的,就像你一边吃早餐一边看动画片,是不是很容易把牛奶洒在衣服上?或者一边写作业一边玩橡皮,是不是半小时的作业写了一小时?并发最大的问题就是:当很多事同时发生的时候,如果没有规则,很容易乱成一锅粥。
我们再回到冰淇淋店的例子:如果有两个收银员,但是只有一个甜筒机,两个叔叔同时给小朋友打甜筒,是不是会出现“甜筒做好了,两个叔叔同时伸手拿,结果甜筒‘啪’的一声掉在地上”的情况?或者两个小朋友同时抢最后一个恐龙蛋甜筒,是不是会推推搡搡,甚至吵架?再比如你和弟弟一起分生日蛋糕,蛋糕上有10颗新鲜的草莓,你们俩同时伸手去抓最大的那颗,“哗啦”一声,蛋糕盘子翻了,奶油蹭了你们俩一身,草莓咕噜噜滚到桌子底下,最后谁都没吃到,是不是特别倒霉?你们俩愣了三秒,然后哇的一声一起哭,妈妈跑过来敲你们的脑壳:“抢什么抢!一人一半不行吗?”你看,妈妈说的“一人一半”,就是并发里最重要的东西——规则。

这种“抢同一个好东西”的场景,你肯定特别熟——体育课玩的抢椅子游戏!10个小朋友围着9把椅子站成一圈,老师放音乐,你们绕着椅子走,音乐一停,所有人必须立刻找椅子坐下,没抢到的就淘汰。你想想,要是没有规则,音乐一停所有人都往上扑,穿43码大鞋的体育委员一屁股坐下去,可能连人带椅子翻,旁边的小美被撞得摔了个屁股墩,哭得稀里哗啦的,最后谁都没玩成。但有了规则:不能推人,抢到同一把椅子的两个人石头剪刀布,赢的坐,输的淘汰,是不是就顺多了?而且抢椅子本身就是超级棒的并发场景:10个小朋友同时找空椅子,同时坐下,要是串行的话,一次只能一个人抢,10个人要抢9轮,玩到下课铃响都玩不完,哪有一局5分钟就结束的爽?你看,并发本身不是坏东西,只要有了小规则,它就能又快又好玩。
我们学校里也有并发的例子哦!上周图书角老师说,以前只有一个还书箱,每天中午还书的小朋友排成长长的队,要等10分钟才能还上,要是动作慢的,赶不上上课还要被老师批评。后来老师加了4个还书箱,同时开放,5个小朋友可以同时还书,只要2分钟就排完了,老师还定了小规则:每人只能还自己借的书,不能帮别人还,还完书要放整齐,不能乱扔。现在中午还书再也不用排队了,大家省下来的时间还能多借两本书看,你看,这就是好的并发:既快,又不会乱。
> 📌 电子版侧边栏:🤓 并发小知识 > 你家的无线路由器就是全世界最忙的并发小能手!它同时让你刷短视频、让你弟弟打在线游戏、让你妈妈开视频会议、给智能音箱放儿歌,甚至还能同时给扫地机器人发指令。要是路由器一次只能做一件事,你们家估计早就吵翻天了:你刷视频的时候,你弟弟的游戏卡成PPT,你妈妈的视频会议断断续续,扫地机器人停在原地不动。路由器能同时服务你们全家的秘密,就是它给每个任务都分了“小时间段”,每个任务做一点点,轮着做,看起来就像同时在做了——这个魔法我们后面第8章会讲哦!
---
并发快多少?我们算一算
你可能会问:并发到底能快多少呀?我们拿最熟悉的冰淇淋店来算一笔账:
- 串行模式:1个收银员,处理1个订单需要30秒,500个小朋友需要 $500 \times 30 = 15000$ 秒,也就是4小时10分钟,最后一个小朋友拿到甜筒的时候,太阳都下山了。
- 并发模式:5个收银员,每个处理100个订单,每个收银员需要 $100 \times 30 = 3000$ 秒,也就是50分钟,比串行快了整整6倍!如果我们有20个收银员,只要 $3000 \div 4 = 750$ 秒,也就是12分半,你拿到甜筒还能赶得上最后一节美术课,画个恐龙蛋甜筒当作业,老师肯定给你打优。
```mermaid gantt title 串行 vs 并发:给500个小朋友打甜筒的时间对比 dateFormat s axisFormat %s秒 section 串行(1个收银员) 处理500个订单 :a, 0, 15000s section 并发(5个收银员) 收银员1处理100个订单 :b1, 0, 3000s 收银员2处理100个订单 :b2, 0, 3000s 收银员3处理100个订单 :b3, 0, 3000s 收银员4处理100个订单 :b4, 0, 3000s 收银员5处理100个订单 :b5, 0, 3000s ```
你看这个时间图,串行的话,500个小朋友要等15000秒,也就是4个多小时,并发的话,5个收银员同时做,只要3000秒,也就是50分钟,快了多少?整整6倍!要是我们有20个收银员,只要15分钟,你拿到甜筒还能赶得上最后一节美术课,画个恐龙蛋甜筒当作业,老师肯定给你打优。
而且并发不只是“快”,还能让更多人享受到服务。要是用串行模式,排在后面的小朋友等4个小时,早就饿得回家了,根本拿不到甜筒;但用并发模式,所有人都能在50分钟内拿到甜筒,不会有人因为等太久而错过。就像你玩抢椅子游戏,串行的话一次只能一个人抢,10个人要玩9轮,后面的小朋友等得都睡着了,并发的话所有人同时玩,5分钟就出结果,大家都玩得尽兴。
---