前言:
做這塊知識展示目的是為了幫助自己對多線程中的知識點(diǎn)做一個(gè)回顧掘剪,所以可能講解上面會很簡單平委,但是重點(diǎn)是要將知識點(diǎn)弄清晰,如果你對多線程不是很了解夺谁,那么可以看看廉赔,當(dāng)然本文中如果存在錯(cuò)誤,也歡迎大家指正匾鸥。
多線程中的隊(duì)列:
串行隊(duì)列昂勉、 并行隊(duì)列、全局隊(duì)列扫腺、主隊(duì)列
執(zhí)行的方法:
同步執(zhí)行和異步執(zhí)行
線程分類:
單線程和多線程,咱們平時(shí)用的最多的就是GCD和NSOperation,他們之間的核心區(qū)別在于GCD是將一個(gè)任務(wù)添加到隊(duì)列中,然后指定任務(wù)執(zhí)行的方法村象,而NSOperation則是將一個(gè)操作添加到隊(duì)列中笆环。
廢話說完了,咱們現(xiàn)在就來看一下厚者,將上面的各種組合做一個(gè)排列看看結(jié)果會是怎么樣的躁劣?
1.串行隊(duì)列,同步執(zhí)行
運(yùn)行結(jié)果
執(zhí)行結(jié)果可以清楚的看到全在主線程執(zhí)行库菲,并且是按照順序執(zhí)行账忘,循環(huán)結(jié)束之后主線程的打印才輸出。
2.串行隊(duì)列,異步執(zhí)行
運(yùn)行結(jié)果
結(jié)果顯示鳖擒,系統(tǒng)開了1條異步線程溉浙,因此全部在線程3執(zhí)行,并且是順序執(zhí)行蒋荚。主線程打印雖然在最上面戳稽,但是這個(gè)先后順序是不確定,如果睡個(gè)0.001秒期升,主線程的打印會混在中間惊奇。
3.并發(fā)隊(duì)列,異步執(zhí)行
運(yùn)行結(jié)果
結(jié)果顯示播赁,主線程的打印還是混在中間不確定的颂郎,因?yàn)楫惒骄€程就是誰也不等誰,可以同時(shí)執(zhí)行。系統(tǒng)開了多條線程容为,并且執(zhí)行的順序也是亂序的
4.并發(fā)隊(duì)列乓序,同步執(zhí)行
運(yùn)行結(jié)果
這個(gè)運(yùn)行結(jié)果和第1種的串行隊(duì)列,同步執(zhí)行是一模一樣的舟奠。 因?yàn)橥饺蝿?wù)的概念就是不允許單開線程竭缝,在這里雖然他是并發(fā)的,可以允許程序同時(shí)運(yùn)行沼瘫,但是系統(tǒng)只有一條線程抬纸,所以他只能按照順序執(zhí)行,所以一旦是同步執(zhí)行的耿戚,前面是什么隊(duì)列都不重要了湿故。
5.主隊(duì)列,異步執(zhí)行
運(yùn)行結(jié)果
結(jié)果顯示有點(diǎn)出人意料膜蛔。主線程在睡會之后才打印坛猪,循環(huán)一直在等著。因?yàn)橹麝?duì)列的任務(wù)雖然會加到主線程中執(zhí)行皂股,但是如果主線程里也有任務(wù)就必須等主線程任務(wù)執(zhí)行完才輪到主隊(duì)列的墅茉。
6.主隊(duì)列,同步執(zhí)行
運(yùn)行結(jié)果
運(yùn)行結(jié)果為程序崩潰
崩潰的原因是循環(huán)等待呜呐,主隊(duì)列的東西要等主線程執(zhí)行完就斤,而因?yàn)槭峭綀?zhí)行不能開線程,所以下面的任務(wù)要等上面的任務(wù)執(zhí)行完蘑辑,所以卡死洋机。
7.子線程死鎖問題1.這里用系統(tǒng)create的方法創(chuàng)建自定義線程,按順序先執(zhí)行任務(wù)1
2.然后遇到一個(gè)異步線程洋魂,把任務(wù)2绷旗,同步線程(包含任務(wù)3),任務(wù)4這三個(gè)東西看成一體放到自定義的串行隊(duì)列中喜鼓,由于是異步線程,直接執(zhí)行下一個(gè)任務(wù)5衔肢,因此異步線程的任務(wù)2和任務(wù)5不確定誰先誰后庄岖,但是任務(wù)1 任務(wù)2 任務(wù)5這三個(gè)東西必定會打印出來
3.看下異步線程里面,都放置在自定義的串行隊(duì)列中膀懈,任務(wù)2之后遇到一個(gè)同步線程顿锰,那么線程阻塞,執(zhí)行同步線程里面的任務(wù)3启搂,由于這個(gè)隊(duì)列里面放置的任務(wù)4按第二步里面的順序率先加入進(jìn)串行隊(duì)列的硼控,當(dāng)同步線程執(zhí)行的時(shí)候,里面的任務(wù)3是還是按照FIFO順序加入到任務(wù)4之后胳赌,那么又造成了任務(wù)4等待任務(wù)3牢撼,任務(wù)3等待任務(wù)4的局面,又死鎖了疑苫。
8.同步任務(wù)的使用場景
運(yùn)行結(jié)果
結(jié)果顯示熏版,“用戶登陸”在主線程打印,后兩個(gè)在異步線程打印捍掺。上面的“用戶登陸”使用同步執(zhí)行撼短,后面的扣費(fèi)和下載都是異步執(zhí)行。所以“用戶登陸”必須第一個(gè)打印出來不管等多久挺勿,然后后面的兩個(gè)異步和主線程打印會不確定順序的打印曲横。這就是日常開發(fā)中,那些后面對其有依賴的必須要先執(zhí)行的任務(wù)使用同步執(zhí)行不瓶,然后反正都要執(zhí)行先后順序無所謂的使用異步執(zhí)行禾嫉。
9.block異步任務(wù)包裹同步任務(wù)
運(yùn)行結(jié)果
因?yàn)檎麄€(gè)block是在異步執(zhí)行的,所以即使里面“用戶登陸”是同步執(zhí)行蚊丐,那也無法在主線程中執(zhí)行熙参,只能開一條異步線程執(zhí)行,后面我故意將一和二任務(wù)換了一下位置麦备。在異步執(zhí)行里面孽椰,因?yàn)轫?xiàng)目是并發(fā)的,可以同時(shí)執(zhí)行凛篙,而且查看動作在用戶登錄前面黍匾,所以它是可以比用戶登錄先執(zhí)行也可能比用戶登錄后執(zhí)行,但是因?yàn)橛脩舻卿浭峭綀?zhí)行的鞋诗,所以下載任務(wù)必須要等用戶登錄任務(wù)先執(zhí)行完他才會執(zhí)行,而主線程跟整個(gè)隊(duì)列里面的任務(wù)之間迈嘹,因?yàn)閠ask是異步的削彬,所以他們之間的先后順序也是隨機(jī)的全庸,隨意主線程執(zhí)行的順序可能在任何一個(gè)位置。
10.全局隊(duì)列,異步執(zhí)行
運(yùn)行結(jié)果
全局隊(duì)列融痛,實(shí)際上就相當(dāng)于并發(fā)隊(duì)列壶笼,所以并發(fā)隊(duì)列異步執(zhí)行,他會開啟多條子線程去執(zhí)行任務(wù)雁刷,并且他跟主線程之間的執(zhí)行順序也是隨機(jī)的覆劈。
11.全局隊(duì)列,同步執(zhí)行
運(yùn)行結(jié)果
全局隊(duì)列沛励,同步執(zhí)行责语,因?yàn)橥綀?zhí)行它不能開啟新線程,所以所有的程序只能在主線程中按照順序依次執(zhí)行目派。全局隊(duì)列的本質(zhì)就是并發(fā)隊(duì)列坤候,只是在后面加入了,“服務(wù)質(zhì)量”企蹭,和“調(diào)度優(yōu)先級” 兩個(gè)參數(shù)白筹,這兩個(gè)參數(shù)一般為了系統(tǒng)間的適配,最好直接填0和0谅摄。
總結(jié):
開不開線程徒河,取決于執(zhí)行任務(wù)的函數(shù),同步不開,并且同步會阻塞線程等到同步任務(wù)執(zhí)行完以后才會執(zhí)行其他任務(wù)送漠,異步開,異步不會阻塞線程顽照。
開幾條線程,取決于隊(duì)列螺男,串行開一條棒厘,并發(fā)開多條(異步)
主隊(duì)列: 專門用來在主線程上調(diào)度任務(wù)的"隊(duì)列",主隊(duì)列不能在其他線程中調(diào)度任務(wù)下隧!
如果主線程上當(dāng)前正在有執(zhí)行的任務(wù)奢人,主隊(duì)列暫時(shí)不會調(diào)度任務(wù)的執(zhí)行!主隊(duì)列同步任務(wù)淆院,會造成死鎖何乎。原因是循環(huán)等待
同步任務(wù)可以隊(duì)列調(diào)度多個(gè)異步任務(wù)前,指定一個(gè)同步任務(wù)土辩,讓所有的異步任務(wù)支救,等待同步任務(wù)執(zhí)行完成,這是依賴關(guān)系拷淘。
全局隊(duì)列:并發(fā)各墨,能夠調(diào)度多個(gè)線程,執(zhí)行效率高启涯,但是相對費(fèi)電贬堵。 串行隊(duì)列效率較低恃轩,省電省流量,或者是任務(wù)之間需要依賴也可以使用串行隊(duì)列黎做。
也可以通過判斷當(dāng)前用戶的網(wǎng)絡(luò)環(huán)境來決定開的線程數(shù)叉跛。WIFI下6條,3G/4G下2~3條蒸殿。