剛接觸開(kāi)發(fā)的童鞋,在學(xué)習(xí)多線程的時(shí)候,往往會(huì)比較吃力.因?yàn)檫@家伙比較抽象,有的時(shí)候較難通過(guò)運(yùn)行代碼直接看到多線程操作應(yīng)該有的實(shí)際效果.和UI相比,多線程部分更注重理解.
所以,希望能通過(guò)這個(gè)故事,幫助大家更好地理解iOS中的多線程.故事是以GCD為主要實(shí)現(xiàn)手段進(jìn)行展開(kāi)的.
OK,那廢話(huà)不多說(shuō),一起走進(jìn)財(cái)富故事匯之屎殼郎老板的公廁生意吧!
屎殼郎老板和它的公廁生意
屎殼郎老板在旅游區(qū)開(kāi)了一間收費(fèi)公廁意荤,招待南來(lái)北往的旅客們急侥。來(lái)上廁所的客人,都是跟著各自的旅行團(tuán)來(lái)的猜年。屎殼郎老板要求上廁所的客人一定要排好隊(duì),一個(gè)一個(gè)來(lái)婆赠,講文明膨蛮,懂禮貌谦趣,謝絕插隊(duì)和隨地大小便等不文明行為。
奇葩的旅客飞主、奇葩的團(tuán)
屎殼郎老板發(fā)現(xiàn)狮惜,來(lái)它這里上廁所的旅客,都非常怪異:
明明坑位很多,排隊(duì)的人也很多碌识,可是有的時(shí)候只有一個(gè)坑位被使用碾篡,有的時(shí)候同時(shí)有好多坑位被使用。
為了弄清楚坑位的使用規(guī)律筏餐,屎殼郎老板對(duì)來(lái)上廁所的旅客开泽,和他們所在的旅行團(tuán)進(jìn)行了調(diào)查統(tǒng)計(jì)分析。
-- 旅客篇 --
根據(jù)旅客的尿意程度魁瞪,屎殼郎老板把旅客分為兩類(lèi):
- 尿急型
- 有備無(wú)患型
尿急型旅客
- 一旦前面的坑位沒(méi)人穆律,這類(lèi)旅客就會(huì)一頭扎進(jìn)坑位中。
通過(guò)數(shù)據(jù)分析导俘,屎殼郎老板還發(fā)現(xiàn):
- 尿急型旅客只認(rèn)準(zhǔn)靠窗的蹲位峦耘,別的蹲位一概不去。
有備無(wú)患型旅客
這類(lèi)旅客其實(shí)不是很急著上廁所旅薄,他們只是看到排隊(duì)上廁所的人多辅髓,想通過(guò)排隊(duì)等坑位的時(shí)間,來(lái)拓展自己的人脈圈的(如此高明的拓展人脈圈手段也是醉了-_-|||)
輪到他們進(jìn)坑的時(shí)候,他們不會(huì)一頭扎進(jìn)去利朵,而是
- 先勾搭他后面的旅客
“嘿哥們兒律想,一起啊~”
看到后面的哥們準(zhǔn)備動(dòng)身了,他才動(dòng)身
屎殼郎老板還發(fā)現(xiàn)绍弟,這類(lèi)旅客:
- 一般會(huì)盡最大可能不用靠窗的坑位技即。
附注
由于尿急型旅客不主動(dòng)招呼排在他后面的旅客,所以樟遣,后面的旅客只有親眼看到尿急旅客已經(jīng)方便完從坑位出來(lái)了而叼,才會(huì)選坑進(jìn)入。
-- 旅行團(tuán)篇 --
研究完旅客豹悬,屎殼郎老板又對(duì)旅客們所在的旅行團(tuán)做了分析和歸類(lèi)葵陵。根據(jù)旅行團(tuán)印發(fā)的《關(guān)于參團(tuán)游客排隊(duì)上公廁秩序的相關(guān)規(guī)定》內(nèi)容進(jìn)行劃分(這旅行團(tuán)管的也太寬了吧-_-|||),大致可以分為三大類(lèi)
- 寬松型
- 嚴(yán)格型
- 苛刻型
寬松型
團(tuán)規(guī):團(tuán)內(nèi)旅客盡量用最短的時(shí)間解決完上廁所問(wèn)題瞻佛,使用哪個(gè)坑位不做限制脱篙。
嚴(yán)格型
團(tuán)規(guī):不管有沒(méi)有空余的坑位,本團(tuán)內(nèi)伤柄,一次只能有一個(gè)旅客在坑位上绊困。
苛刻型
團(tuán)規(guī):本團(tuán)內(nèi)的旅客,只能使用靠窗的那個(gè)坑位适刀。
屎殼郎老板很開(kāi)心秤朗,因?yàn)橛辛诉@兩份資料,他就能提前判斷出笔喉,下一次取视,會(huì)有幾個(gè)旅客同時(shí)進(jìn)坑,以及他們分別會(huì)用幾號(hào)坑位常挚。
屎殼郎老板的測(cè)試題
OK作谭,屎殼郎老板收集到的情報(bào)我們已經(jīng)掌握了,那么奄毡,屎殼郎老板給大家出了一份測(cè)試題丢早,我們一起來(lái)試著分析下吧!
題目:
假設(shè)這次排隊(duì)的旅客有四個(gè):
其中 三個(gè)來(lái)自名叫“嚴(yán)格旅行團(tuán)”的嚴(yán)格型旅行團(tuán)
另外兩個(gè)來(lái)自名叫“寬松旅行團(tuán)”的寬松型團(tuán)
根據(jù)從前到后的順序秧倾,他們分別是:
* 小A同學(xué):來(lái)自寬松團(tuán)怨酝,有備無(wú)患型
* 小B同學(xué):來(lái)自寬松團(tuán),有備無(wú)患型
* 小C同學(xué):來(lái)自嚴(yán)格團(tuán)那先,尿急型
* 小D同學(xué):來(lái)自寬松團(tuán)农猬,有備無(wú)患型
* 小E同學(xué):來(lái)自嚴(yán)格團(tuán),尿急型
模擬入坑過(guò)程
第一階段
- 輪到排在最前面的小 A 同學(xué)入坑了售淡,由于小 A是個(gè)有備無(wú)患型的斤葱,扭過(guò)頭來(lái)招呼小 B:“嘿哥們兒一起啊”
- 小 B 同學(xué)也興奮的扭過(guò)頭招呼小 C:" 嘿哥們慷垮,一起啊~"
- 小 C 已經(jīng)憋很久了,拔腿就準(zhǔn)備往蹲位里沖揍堕。
- 小 B 看到小 C 準(zhǔn)備動(dòng)身了料身,自己也整理整理準(zhǔn)備動(dòng)身。
- 小 A 看小 B 準(zhǔn)備動(dòng)身了衩茸,自己馬上動(dòng)身走向坑位芹血。因?yàn)槭怯袀錈o(wú)患型,所以小 A 討厭靠窗的1號(hào)蹲位楞慈,選擇了2號(hào)蹲位幔烛。
- 小 B 動(dòng)身前也思考了一下,我們團(tuán)允許多個(gè)團(tuán)員同時(shí)入坑囊蓝。于是小 B 也動(dòng)身了饿悬。有備無(wú)患型,討厭靠窗的1號(hào)蹲位聚霜,2號(hào)蹲位又有人了狡恬,于是選擇了3號(hào)蹲位
- 雖然便意濃濃,但小 C 還是略一思忖:我們團(tuán)規(guī)定一次只能一個(gè)人入坑蝎宇,前面入坑的兩個(gè)都不是我們團(tuán)的傲宜,看來(lái)我能入坑。然后看了一眼坑位:我喜歡的靠窗1號(hào)坑正好沒(méi)人用夫啊!然后拔腿奔向了1號(hào)坑位。
總結(jié):第一階段同時(shí)入坑的有ABC三 位同學(xué)辆憔,分別使用了2號(hào)坑撇眯、3號(hào)坑和1號(hào)坑
第二階段
- 親眼看見(jiàn)小 C 從蹲位里面帶幸福的走出來(lái),小 D 知道虱咧,輪到自己了熊榛。于是招呼小 E 一起入坑
- 小 E 二話(huà)不說(shuō)低著頭就準(zhǔn)備往坑里沖。小 D 見(jiàn)狀略一思忖:我們團(tuán)允許多個(gè)本團(tuán)成員一起入坑腕巡,雖然之前兩個(gè)團(tuán)員小 A 和小 B 還沒(méi)出來(lái)(假設(shè)小 A 和小B 解決的比較慢)玄坦,但我還是可以入坑的。 于是動(dòng)身選坑位
- 1號(hào)坑位雖然沒(méi)人绘沉,但是小 D不喜歡煎楣,2號(hào)3號(hào)有人了(小 A 小 B 在里面),所以小 D 選擇了4號(hào)坑位
- 小 E 臨行前也簡(jiǎn)單思考了下:我們團(tuán)沒(méi)有人在蹲位中车伞,1號(hào)蹲位沒(méi)有人择懂。于是小 E 沖向了1號(hào)蹲位。
總結(jié):第二階段同時(shí)入坑的有 DE 兩位同學(xué)另玖,分別使用了4號(hào)坑和1號(hào)坑困曙。
驗(yàn)證
OK分析完成表伦,我們用代碼來(lái)驗(yàn)證下是不是這樣
代碼們
可以嘗試自己運(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)的有備無(wú)患型小 A
dispatch_async( relaxingTeam, ^{
// 讓小 A 便便的時(shí)間長(zhǎng)一點(diǎn)
for (int i = 0 ; i <= 1000 ; i++)
{
NSLog(@"我是小 A慷丽,我在便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
}
});
// 創(chuàng)建與小 A 相似的小 B
dispatch_async( relaxingTeam, ^{
// 讓小 B 便便的時(shí)間也長(zhǎng)一點(diǎn)
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 便的時(shí)間短一點(diǎn)
for (int i = 0 ; i <= 10 ; i++)
{
NSLog(@"我是小 C,我在也便便 -- 完成度 %%%d ---%@",i * 10,[NSThread currentThread]);
}
});
// 寬松團(tuán)的有備無(wú)患型小 D
dispatch_async( relaxingTeam, ^{
// 讓小 D 便便的時(shí)間也長(zhǎng)一點(diǎn)
for (int i = 0 ; i <= 1000 ; i++)
{
NSLog(@"我是小 D要糊,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
}
});
// 嚴(yán)格團(tuán)的尿急小 E
dispatch_sync( seriouslyTeam, ^{
// 讓小 E 便便的時(shí)間也長(zhǎng)一點(diǎn)
for (int i = 0 ; i <= 1000 ; i++)
{
NSLog(@"我是小 E纲熏,我在也便便 -- 完成度 %%%.3f ---%@",i * 0.1,[NSThread currentThread]);
}
});
}
總結(jié)
嗯哼~ 故事講完了。沒(méi)看明白杨耙?不知道這鬼東西有什么卵用赤套?不妨看看下面的對(duì)照表哦:
概念對(duì)照表
- 旅客 對(duì)應(yīng) 任務(wù)
1.1 尿急型旅客 對(duì)應(yīng) 同步任務(wù)
1.2 有備無(wú)患型旅客 對(duì)應(yīng) 異步任務(wù) - 旅行團(tuán) 對(duì)應(yīng) 隊(duì)列
2.1 寬松型旅行團(tuán) 對(duì)應(yīng) 并發(fā)隊(duì)列(Concurrent
Dispatch Queue)
2.2 嚴(yán)格型旅行團(tuán) 對(duì)應(yīng) 串行隊(duì)列(Serial
Dispatch Queue)
2.3 苛刻型旅行團(tuán) 對(duì)應(yīng) 主隊(duì)列(Main Queue) - 蹲位 對(duì)應(yīng) 線程
3.1 靠窗蹲位 對(duì)應(yīng) 主線程
(所有涉及 UI 展示方面的任務(wù)都要在主線程中執(zhí)行,所以... 主線程就是靠窗的蹲位啦...)
3.2 其他蹲位 對(duì)應(yīng) 子線程
應(yīng)用
嘗試用多線程知識(shí)實(shí)現(xiàn):分 六個(gè)任務(wù)別打印A珊膜、B容握、C、D车柠、E 剔氏、F 六個(gè)字母,要求:A打印完后打印 B 和 C(要求BC幾乎同時(shí)打又竦弧)谈跛,C 打印完后打印D、E塑陵、F( DEF幾乎同時(shí)打印)
最后的最后
一個(gè)故事并不能將多線程的知識(shí)完全講清楚感憾,只是希望,這篇小小的令花、有點(diǎn)怪誕阻桅、槽點(diǎn)滿(mǎn)滿(mǎn)的故事,能帶給大家一點(diǎn)輕松快樂(lè)的好心情兼都。會(huì)心一笑嫂沉,然后帶著這份好心情,一起繼續(xù)在這個(gè)充滿(mǎn)魔法的編程世界里前行吧~ _
PS. 剛編出來(lái)這個(gè)故事時(shí)候扮碧,每次上廁所看到蹲位都忍不住想笑... 不過(guò)想到邊排泄邊傻笑可能有點(diǎn)怪怪的...所以還是忍住了= =
PPS. 屎殼郎老板的故事還沒(méi)有結(jié)束哦趟章!下一篇——《屎殼郎老板的神奇寶貝——蹲位獸》,和大家一起探秘屎殼郎老板公廁的蹲位慎王,順便聊一點(diǎn)runloop的小知識(shí)_