聽故事學(xué)iOS系列 - 屎殼郎老板和它的收費(fèi)公廁(一個故事搞懂多線程)
屎殼郎老板和它的公廁生意
屎殼郎老板在旅游區(qū)開了一間收費(fèi)公廁,招待南來北往的旅客們。來上廁所的客人,都是跟著各自的旅行團(tuán)來的。屎殼郎老板要求上廁所的客人一定要排好隊,一個一個來,講文明,懂禮貌,謝絕插隊和隨地大小便等不文明行為。
奇葩的旅客、奇葩的團(tuán)
屎殼郎老板發(fā)現(xiàn),來它這里上廁所的旅客,都非常怪異:
明明坑位很多,排隊的人也很多,可是有的時候只有一個坑位被使用,有的時候同時有好多坑位被使用。
為了弄清楚坑位的使用規(guī)律,屎殼郎老板對來上廁所的旅客,和他們所在的旅行團(tuán)進(jìn)行了調(diào)查統(tǒng)計分析。
-- 旅客篇 --
根據(jù)旅客的尿意程度,屎殼郎老板把旅客分為兩類:
- 尿急型
- 有備無患型
尿急型旅客
- 一旦前面的坑位沒人,這類旅客就會一頭扎進(jìn)坑位中。
通過數(shù)據(jù)分析,屎殼郎老板還發(fā)現(xiàn):
- 尿急型旅客只認(rèn)準(zhǔn)靠窗的蹲位,別的蹲位一概不去。
有備無患型旅客
這類旅客其實不是很急著上廁所,他們只是看到排隊上廁所的人多,想通過排隊等坑位的時間,來拓展自己的人脈圈的(如此高明的拓展人脈圈手段也是醉了-_-|||)
輪到他們進(jìn)坑的時候,他們不會一頭扎進(jìn)去,而是
- 先勾搭他后面的旅客
“嘿哥們兒,一起啊~”
看到后面的哥們準(zhǔn)備動身了,他才動身
屎殼郎老板還發(fā)現(xiàn),這類旅客:
- 一般會盡最大可能不用靠窗的坑位。
附注
由于尿急型旅客不主動招呼排在他后面的旅客,所以,后面的旅客只有親眼看到尿急旅客已經(jīng)方便完從坑位出來了,才會選坑進(jìn)入。
-- 旅行團(tuán)篇 --
研究完旅客,屎殼郎老板又對旅客們所在的旅行團(tuán)做了分析和歸類。根據(jù)旅行團(tuán)印發(fā)的《關(guān)于參團(tuán)游客排隊上公廁秩序的相關(guān)規(guī)定》內(nèi)容進(jìn)行劃分(這旅行團(tuán)管的也太寬了吧-_-|||),大致可以分為三大類
- 寬松型
- 嚴(yán)格型
- 苛刻型
寬松型
團(tuán)規(guī):團(tuán)內(nèi)旅客盡量用最短的時間解決完上廁所問題,使用哪個坑位不做限制。
嚴(yán)格型
團(tuán)規(guī):不管有沒有空余的坑位,本團(tuán)內(nèi),一次只能有一個旅客在坑位上。
苛刻型
團(tuán)規(guī):本團(tuán)內(nèi)的旅客,只能使用靠窗的那個坑位。
屎殼郎老板很開心,因為有了這兩份資料,他就能提前判斷出,下一次,會有幾個旅客同時進(jìn)坑,以及他們分別會用幾號坑位。
屎殼郎老板的測試題
OK,屎殼郎老板收集到的情報我們已經(jīng)掌握了,那么,屎殼郎老板給大家出了一份測試題,我們一起來試著分析下吧!
題目: 假設(shè)這次排隊的旅客有四個: 其中 三個來自名叫“嚴(yán)格旅行團(tuán)”的嚴(yán)格型旅行團(tuán) 另外兩個來自名叫“寬松旅行團(tuán)”的寬松型團(tuán) 根據(jù)從前到后的順序,他們分別是: * 小A同學(xué):來自寬松團(tuán),有備無患型 * 小B同學(xué):來自寬松團(tuán),有備無患型 * 小C同學(xué):來自嚴(yán)格團(tuán),尿急型 * 小D同學(xué):來自寬松團(tuán),有備無患型 * 小E同學(xué):來自嚴(yán)格團(tuán),尿急型
模擬入坑過程
第一階段
- 輪到排在最前面的小 A 同學(xué)入坑了,由于小 A是個有備無患型的,扭過頭來招呼小 B:“嘿哥們兒~一起啊~”
- 小 B 同學(xué)也興奮的扭過頭招呼小 C:" 嘿哥們,一起啊~"
- 小 C 已經(jīng)憋很久了,拔腿就準(zhǔn)備往蹲位里沖。
- 小 B 看到小 C 準(zhǔn)備動身了,自己也整理整理準(zhǔn)備動身。
- 小 A 看小 B 準(zhǔn)備動身了,自己馬上動身走向坑位。因為是有備無患型,所以小 A 討厭靠窗的1號蹲位,選擇了2號蹲位。
- 小 B 動身前也思考了一下,我們團(tuán)允許多個團(tuán)員同時入坑。于是小 B 也動身了。有備無患型,討厭靠窗的1號蹲位,2號蹲位又有人了,于是選擇了3號蹲位
- 雖然便意濃濃,但小 C 還是略一思忖:我們團(tuán)規(guī)定一次只能一個人入坑,前面入坑的兩個都不是我們團(tuán)的,看來我能入坑。然后看了一眼坑位:我喜歡的靠窗1號坑正好沒人用!然后拔腿奔向了1號坑位。
總結(jié):第一階段同時入坑的有ABC三 位同學(xué),分別使用了2號坑、3號坑和1號坑
第二階段
- 親眼看見小 C 從蹲位里面帶幸福的走出來,小 D 知道,輪到自己了。于是招呼小 E 一起入坑
- 小 E 二話不說低著頭就準(zhǔn)備往坑里沖。小 D 見狀略一思忖:我們團(tuán)允許多個本團(tuán)成員一起入坑,雖然之前兩個團(tuán)員小 A 和小 B 還沒出來(假設(shè)小 A 和小B 解決的比較慢),但我還是可以入坑的。 于是動身選坑位
- 1號坑位雖然沒人,但是小 D不喜歡,2號3號有人了(小 A 小 B 在里面),所以小 D 選擇了4號坑位
- 小 E 臨行前也簡單思考了下:我們團(tuán)沒有人在蹲位中,1號蹲位沒有人。于是小 E 沖向了1號蹲位。
總結(jié):第二階段同時入坑的有 DE 兩位同學(xué),分別使用了4號坑和1號坑。
驗證
OK~分析完成,我們用代碼來驗證下是不是這樣~
代碼們
可以嘗試自己運(yùn)行下看看結(jié)果是不是和我們分析的一樣哦!
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- {
- // 創(chuàng)建名叫“嚴(yán)格旅行團(tuán)”的嚴(yán)格型旅行團(tuán)
- dispatch_queue_t seriouslyTeam = dispatch_queue_create("com.azen.xu", DISPATCH_QUEUE_SERIAL);
- // 創(chuàng)建名叫“寬松旅行團(tuán)”的寬松型旅行團(tuán)
- dispatch_queue_t relaxingTeam = dispatch_queue_create("com.azen.xu",DISPATCH_QUEUE_CONCURRENT);
- // 創(chuàng)建寬松團(tuán)的有備無患型小 A
- dispatch_async( relaxingTeam, ^{
- // 讓小 A 便便的時間長一點
- for (int i = 0 ; i <= 1000 ; i++)
- {
- NSLog(@"我是小 A,我在便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
- }
- });
- // 創(chuàng)建與小 A 相似的小 B
- dispatch_async( relaxingTeam, ^{
- // 讓小 B 便便的時間也長一點
- for (int i = 0 ; i <= 1000 ; i++)
- {
- NSLog(@"我是小 B,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
- }
- });
- // 創(chuàng)建嚴(yán)格團(tuán)的尿急小 C
- dispatch_sync(seriouslyTeam, ^{
- // 小 C 便的時間短一點
- for (int i = 0 ; i <= 10 ; i++)
- {
- NSLog(@"我是小 C,我在也便便 -- 完成度 %%%d ---%@",i * 10,[NSThread currentThread]);
- }
- });
- // 寬松團(tuán)的有備無患型小 D
- dispatch_async( relaxingTeam, ^{
- // 讓小 D 便便的時間也長一點
- for (int i = 0 ; i <= 1000 ; i++)
- {
- NSLog(@"我是小 D,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
- }
- });
- // 嚴(yán)格團(tuán)的尿急小 E
- dispatch_sync( seriouslyTeam, ^{
- // 讓小 E 便便的時間也長一點
- for (int i = 0 ; i <= 1000 ; i++)
- {
- NSLog(@"我是小 E,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
- }
- });
- }
總結(jié)
嗯哼~ 故事講完了。沒看明白?不知道這鬼東西有什么卵用?不妨看看下面的對照表哦:
概念對照表
- 旅客 對應(yīng) 任務(wù)
1.1 尿急型旅客 對應(yīng) 同步任務(wù)
1.2 有備無患型旅客 對應(yīng) 異步任務(wù) - 旅行團(tuán) 對應(yīng) 隊列
2.1 寬松型旅行團(tuán) 對應(yīng) 并發(fā)隊列(Concurrent
Dispatch Queue)
2.2 嚴(yán)格型旅行團(tuán) 對應(yīng) 串行隊列(Serial
Dispatch Queue)
2.3 苛刻型旅行團(tuán) 對應(yīng) 主隊列(Main Queue) - 蹲位 對應(yīng) 線程
3.1 靠窗蹲位 對應(yīng) 主線程
(所有涉及 UI 展示方面的任務(wù)都要在主線程中執(zhí)行,所以... 主線程就是靠窗的蹲位啦...)
3.2 其他蹲位 對應(yīng) 子線程
應(yīng)用
嘗試用多線程知識實現(xiàn):分 六個任務(wù)別打印A、B、C、D、E 、F 六個字母,要求:A打印完后打印 B 和 C(要求BC幾乎同時打?。?,C 打印完后打印D、E、F( DEF幾乎同時打印)
最后的最后
一個故事并不能將多線程的知識完全講清楚,只是希望,這篇小小的、有點怪誕、槽點滿滿的故事,能帶給大家一點輕松快樂的好心情。會心一笑,然后帶著這份好心情,一起繼續(xù)在這個充滿魔法的編程世界里前行吧~ ^_^
PS. 剛編出來這個故事時候,每次上廁所看到蹲位都忍不住想笑... 不過想到邊排泄邊傻笑可能有點怪怪的...所以還是忍住了= =
PPS. 屎殼郎老板的故事還沒有結(jié)束哦!下一篇——《屎殼郎老板的神奇寶貝——蹲位獸》,和大家一起探秘屎殼郎老板公廁的蹲位,順便聊一點runloop的小知識^_^