請(qǐng)寫出程序執(zhí)行后的輸出結(jié)果:
- (void)threadTest {
NSLog(@"0");
dispatch_queue_t queue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"1");
dispatch_async(queue, ^{
sleep(5);
NSLog(@"2");
});
dispatch_async(queue, ^{
sleep(1);
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
結(jié)果:0,1,4,5,3,2
解析:本題主要考察對(duì)隊(duì)列、線程執(zhí)行順序、同步、異步的理解和掌握。
首先,代碼中創(chuàng)建的是并發(fā)隊(duì)列,則表示CPU會(huì)在線程間快速切換,從而影響代碼的輸出結(jié)果,所以特意加了線程休眠操作以保證程序的輸出固定,下面我們剖析執(zhí)行過程:
第一步輸出0是毋庸置疑的,不做解釋,
第二步創(chuàng)建了一個(gè)并發(fā)隊(duì)列,
第三步同步執(zhí)行代碼,不會(huì)開啟新的線程,會(huì)阻塞當(dāng)前線程(主線程a),等待內(nèi)部block里代碼執(zhí)行完才會(huì)結(jié)束,我們來到block內(nèi)部繼續(xù)分析代碼執(zhí)行:
輸出1也不做解釋,
繼續(xù)執(zhí)行,異步執(zhí)行一段代碼,此時(shí)會(huì)開啟新的線程b來執(zhí)行block內(nèi)部的代碼,不會(huì)阻塞線程,代碼繼續(xù)執(zhí)行,同理異步開啟一個(gè)新的線程c來執(zhí)行block內(nèi)部的代碼,繼續(xù)執(zhí)行,輸出4,至此,a線程里的block執(zhí)行完畢,代碼繼續(xù)向下執(zhí)行,輸出5,
a線程實(shí)行完畢,由于線程b和c有休眠操作,會(huì)進(jìn)入休眠狀態(tài),待休眠結(jié)束,會(huì)繼續(xù)執(zhí)行,因?yàn)榫€程c的休眠時(shí)間短,故線程c先執(zhí)行,假設(shè)線程b和c在同等條件下執(zhí)行,則c線程會(huì)先于b線程結(jié)束執(zhí)行,故輸出順序?yàn)?,2,
由此我們最終得出順序?yàn)?0,1,4,5,3,2
結(jié)束語:此題可以有多種變形:如將并發(fā)隊(duì)列改為串行隊(duì)列,將同步改為異步,不同的組合會(huì)有不同的結(jié)果,有興趣的可以自己嘗試一下(有可能會(huì)出現(xiàn)死鎖的情況哦,關(guān)于死鎖的情況以后會(huì)單獨(dú)解析)。