转载

听故事搞懂多线程开发-- 屎壳郎老板和它的收费公厕

刚接触开发的童鞋,在学习多线程的时候,往往会比较吃力.因为这家伙比较抽象,有的时候较难通过运行代码直接看到多线程操作应该有的实际效果.和UI相比,多线程部分更注重理解.

所以,希望能通过这个故事,帮助大家更好地理解iOS中的多线程.故事是以GCD为主要实现手段进行展开的.

OK,那废话不多说,一起走进财富故事汇之屎壳郎老板的公厕生意吧!

屎壳郎老板和它的公厕生意

屎壳郎老板在旅游区开了一间收费公厕,招待南来北往的旅客们。来上厕所的客人,都是跟着各自的旅行团来的。屎壳郎老板要求上厕所的客人一定要排好队,一个一个来,讲文明,懂礼貌,谢绝插队和随地大小便等不文明行为。

奇葩的旅客、奇葩的团

屎壳郎老板发现,来它这里上厕所的旅客,都非常怪异:

明明坑位很多,排队的人也很多,可是有的时候只有一个坑位被使用,有的时候同时有好多坑位被使用。

为了弄清楚坑位的使用规律,屎壳郎老板对来上厕所的旅客,和他们所在的旅行团进行了调查统计分析。

-- 旅客篇 --

根据旅客的尿意程度,屎壳郎老板把旅客分为两类:

  • 尿急型

  • 有备无患型

尿急型旅客

  • 一旦前面的坑位没人,这类旅客就会一头扎进坑位中。

通过数据分析,屎壳郎老板还发现:

  • 尿急型旅客只认准靠窗的蹲位,别的蹲位一概不去。

有备无患型旅客

这类旅客其实不是很急着上厕所,他们只是看到排队上厕所的人多,想通过排队等坑位的时间,来拓展自己的人脉圈的(如此高明的拓展人脉圈手段也是醉了-_-|||)

轮到他们进坑的时候,他们不会一头扎进去,而是

  • 先勾搭他后面的旅客

“嘿哥们儿,一起啊~”

看到后面的哥们准备动身了,他才动身

屎壳郎老板还发现,这类旅客:

  • 一般会尽最大可能不用靠窗的坑位。

附注: 由于尿急型旅客不主动招呼排在他后面的旅客,所以,后面的旅客只有亲眼看到尿急旅客已经方便完从坑位出来了,才会选坑进入。

-- 旅行团篇 --

研究完旅客,屎壳郎老板又对旅客们所在的旅行团做了分析和归类。根据旅行团印发的《关于参团游客排队上公厕秩序的相关规定》内容进行划分(这旅行团管的也太宽了吧-_-|||),大致可以分为三大类

  • 宽松型

  • 严格型

  • 苛刻型

宽松型

  • 团规:团内旅客尽量用最短的时间解决完上厕所问题,使用哪个坑位不做限制。

严格型

  • 团规:不管有没有空余的坑位,本团内,一次只能有一个旅客在坑位上。

苛刻型

  • 团规:本团内的旅客,只能使用靠窗的那个坑位。

屎壳郎老板很开心,因为有了这两份资料,他就能提前判断出,下一次,会有几个旅客同时进坑,以及他们分别会用几号坑位。

屎壳郎老板的测试题

OK,屎壳郎老板收集到的情报我们已经掌握了,那么,屎壳郎老板给大家出了一份测试题,我们一起来试着分析下吧!

题目:

假设这次排队的旅客有四个:

其中 三个来自名叫“严格旅行团”的严格型旅行团

另外两个来自名叫“宽松旅行团”的宽松型团

根据从前到后的顺序,他们分别是:

* 小A同学:来自宽松团,有备无患型

* 小B同学:来自宽松团,有备无患型

* 小C同学:来自严格团,尿急型

* 小D同学:来自宽松团,有备无患型

* 小E同学:来自严格团,尿急型

模拟入坑过程

第一阶段

  1. 轮到排在最前面的小 A 同学入坑了,由于小 A是个有备无患型的,扭过头来招呼小 B:“嘿哥们儿~一起啊~”

  2. 小 B 同学也兴奋的扭过头招呼小 C:" 嘿哥们,一起啊~"

  3. 小 C 已经憋很久了,拔腿就准备往蹲位里冲。

  4. 小 B 看到小 C 准备动身了,自己也整理整理准备动身。

  5. 小 A 看小 B 准备动身了,自己马上动身走向坑位。因为是有备无患型,所以小 A 讨厌靠窗的1号蹲位,选择了2号蹲位。

  6. 小 B 动身前也思考了一下,我们团允许多个团员同时入坑。于是小 B 也动身了。有备无患型,讨厌靠窗的1号蹲位,2号蹲位又有人了,于是选择了3号蹲位

  7. 虽然便意浓浓,但小 C 还是略一思忖:我们团规定一次只能一个人入坑,前面入坑的两个都不是我们团的,看来我能入坑。然后看了一眼坑位:我喜欢的靠窗1号坑正好没人用!然后拔腿奔向了1号坑位。

总结:第一阶段同时入坑的有ABC三 位同学,分别使用了2号坑、3号坑和1号坑

第二阶段

  1. 亲眼看见小 C 从蹲位里面带幸福的走出来,小 D 知道,轮到自己了。于是招呼小 E 一起入坑

  2. 小 E 二话不说低着头就准备往坑里冲。小 D 见状略一思忖:我们团允许多个本团成员一起入坑,虽然之前两个团员小 A 和小 B 还没出来(假设小 A 和小B 解决的比较慢),但我还是可以入坑的。 于是动身选坑位

  3. 1号坑位虽然没人,但是小 D不喜欢,2号3号有人了(小 A 小 B 在里面),所以小 D 选择了4号坑位

  4. 小 E 临行前也简单思考了下:我们团没有人在蹲位中,1号蹲位没有人。于是小 E 冲向了1号蹲位。

总结:第二阶段同时入坑的有 DE 两位同学,分别使用了4号坑和1号坑。

验证

OK~分析完成,我们用代码来验证下是不是这样~

代码们

听故事搞懂多线程开发-- 屎壳郎老板和它的收费公厕

屎壳郎老板的测试题 - 代码验证.png

可以尝试自己运行下看看结果是不是和我们分析的一样哦!

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  //  创建名叫“严格旅行团”的严格型旅行团  dispatch_queue_t seriouslyTeam = dispatch_queue_create("com.azen.xu", DISPATCH_QUEUE_SERIAL);  //  创建名叫“宽松旅行团”的宽松型旅行团  dispatch_queue_t relaxingTeam = dispatch_queue_create("com.azen.xu",DISPATCH_QUEUE_CONCURRENT);  //  创建宽松团的有备无患型小 A  dispatch_async( relaxingTeam, ^{   //  让小 A 便便的时间长一点   for (int i = 0 ; i <= 1000 ; i++)   {    NSLog(@"我是小 A,我在便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);   }  });  //  创建与小 A 相似的小 B  dispatch_async( relaxingTeam, ^{   //  让小 B 便便的时间也长一点   for (int i = 0 ; i <= 1000 ; i++)   {    NSLog(@"我是小 B,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);   }  });  //  创建严格团的尿急小 C  dispatch_sync(seriouslyTeam, ^{   //  小 C 便的时间短一点   for (int i = 0 ; i <= 10 ; i++)   {    NSLog(@"我是小 C,我在也便便 -- 完成度 %%%d ---%@",i * 10,[NSThread currentThread]);   }  });  //  宽松团的有备无患型小 D  dispatch_async( relaxingTeam, ^{   //  让小 D 便便的时间也长一点   for (int i = 0 ; i <= 1000 ; i++)   {    NSLog(@"我是小 D,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);   }  });  //  严格团的尿急小 E  dispatch_sync( seriouslyTeam, ^{   //  让小 E 便便的时间也长一点   for (int i = 0 ; i <= 1000 ; i++)   {    NSLog(@"我是小 E,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);   }  }); } 

总结

嗯哼~ 故事讲完了。没看明白?不知道这鬼东西有什么卵用?不妨看看下面的对照表哦:

概念对照表

旅客 对应 任务

  • 尿急型旅客 对应 同步任务

  • 有备无患型旅客 对应 异步任务

旅行团 对应 队列

  • 宽松型旅行团 对应 并发队列(Concurrent Dispatch Queu e)

  • 严格型旅行团 对应 串行队列(Serial D ispatch Q ueue)

  • 苛刻型旅行团 对应 主队列(Main Queue)

蹲位 对应 线程

  • 靠窗蹲位 对应 主线程

(所有涉及 UI 展示方面的任务都要在主线程中执行,所以... 主线程就是靠窗的蹲位啦...)

  • 其他蹲位 对应 子线程

应用

尝试用多线程知识实现:分 六个任务别打印A、B、C、D、E 、F 六个字母,要求:A打印完后打印 B 和 C(要求BC几乎同时打印),C 打印完后打印D、E、F( DEF几乎同时打印)

最后的最后

一个故事并不能将多线程的知识完全讲清楚,只是希望,这篇小小的、有点怪诞、槽点满满的故事,能带给大家一点轻松快乐的好心情。会心一笑,然后带着这份好心情,一起继续在这个充满魔法的编程世界里前行吧~ ^_^

PS. 刚编出来这个故事时候,每次上厕所看到蹲位都忍不住想笑... 不过想到边排泄边傻笑可能有点怪怪的...所以还是忍住了= =

PPS. 屎壳郎老板的故事还没有结束哦!下一篇——《屎壳郎老板的神奇宝贝——蹲位兽》,和大家一起探秘屎壳郎老板公厕的蹲位,顺便聊一点runloop的小知识^_^

正文到此结束
Loading...