在程序開發(fā)的時(shí)候,我們會(huì)經(jīng)常使用到多線程,相信很多程序員對(duì)多線程這一塊都很頭疼,如果我們想用好多線程,就需要加深對(duì)多線程的理解,這樣我們?cè)谑褂玫臅r(shí)候才會(huì)得心應(yīng)手,所以在工作閑暇之余我總結(jié)了一些自己對(duì)多線程的理解,如有不足之處,請(qǐng)各位看客老爺多多指出.
言歸正傳,大家都知道在iOS開發(fā)中,有四種多線程技術(shù)的使用,block除外.即:
- pthread
- NSThread
- GCD
- NSOperation
因?yàn)閜thread的使用難度較大,切線程的生命周期需要程序員自己管理,所以我在平時(shí)的工作中也很少用到這樣的技術(shù),由于本人能力有限,所以下面我只會(huì)分析和總結(jié)NSThread,GCD和NSOperation.
在正式總結(jié)之前有一點(diǎn)需要大家注意:
同一個(gè)方法內(nèi)的代碼,都是在相同線程執(zhí)行的(block除外)
NSThread
- NSThread在創(chuàng)建之后需要手動(dòng)啟動(dòng),即start方法
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);
- detach方法為分離一個(gè)線程去執(zhí)行方法,這個(gè)則為自動(dòng)執(zhí)行
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
- performSelectorInBackground也是自動(dòng)執(zhí)行,切為隱式創(chuàng)建線程
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);
前兩種方法可以通過(guò)指定不同的target來(lái)執(zhí)行不同類的@selector,而performSelectorInBackground方法是 NSObject 的分類方法,它會(huì)自動(dòng)在后臺(tái)執(zhí)行@selector方法,performSelectorInBackground執(zhí)行哪個(gè)類的方法取決于它的調(diào)用對(duì)象,所以不要看見(jiàn)target就寫self,這也是很多新手常犯的錯(cuò)誤
線程的狀態(tài)
線程劃分為物種狀態(tài),即:
- 創(chuàng)建
實(shí)例化線程對(duì)象 - 就緒
向線程對(duì)象發(fā)送 start 消息,線程對(duì)象被加入可調(diào)度線程池等待 CPU 調(diào)度
detach 方法和 performSelectorInBackground 方法會(huì)直接實(shí)例化一個(gè)線程對(duì)象并加入可調(diào)度線程池 - 運(yùn)行
CPU 負(fù)責(zé)調(diào)度可調(diào)度線程池中線程的執(zhí)行
線程執(zhí)行完成之前,狀態(tài)可能會(huì)在就緒和運(yùn)行之間來(lái)回切換
就緒和運(yùn)行之間的狀態(tài)變化由 CPU 負(fù)責(zé),程序員不能干預(yù) - 阻塞
當(dāng)滿足某個(gè)預(yù)定條件時(shí),可以使用休眠或鎖阻塞線程執(zhí)行
sleepForTimeInterval:休眠指定時(shí)長(zhǎng)
sleepUntilDate:休眠到指定日期
@synchronized(self):互斥鎖 - 死亡
- 正常死亡
線程執(zhí)行完畢 - 非正常死亡
當(dāng)滿足某個(gè)條件后,在線程內(nèi)部中止執(zhí)行
[NSThread exit];
當(dāng)滿足某個(gè)條件后,在主線程中止線程對(duì)象
注意:在終止線程之前,應(yīng)該注意釋放之前分配的對(duì)象!
注意:線程從就緒和運(yùn)行狀態(tài)之間的切換是由 CPU 負(fù)責(zé)的,程序員無(wú)法干預(yù)
也就是說(shuō)當(dāng) 當(dāng)前任務(wù) 加入到 可調(diào)度線程池之后 我們無(wú)法阻止當(dāng)前線程的執(zhí)行,只能在執(zhí)行代碼中提前處理好終止條件.
就先寫到這,我會(huì)在后面的博客繼續(xù)分析多線程技術(shù)和橫縱向的對(duì)比.