這篇主要寫的是1、同異步派發(fā)(dispatch_async荠列、dispatch_sync)
2类浪、串并行隊(duì)列(DISPATCH_QUEUE_SERIAL、DISPATCH_QUEUE_CONCURRENT)
1.同異步派發(fā)(dispatch_async肌似、dispatch_sync)
- dispatch_sync:同步派發(fā)费就。當(dāng)走到dispatch_sync 時(shí),不直接返回川队,而要直接走完block的代碼.
示例:
char *sync = "sycnQ";
dispatch_queue_t syncQ = dispatch_queue_create(sync, DISPATCH_QUEUE_SERIAL);
dispatch_sync(syncQ, ^{
NSLog(@"同步串行隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
NSLog(@"同步并行隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
//這個(gè)會造成線程阻塞力细,因?yàn)閐ispatch_sync要走完block的代碼 而主線程要等待block走完 才會走 所以同步主隊(duì)列會造成阻塞crash
dispatch_sync(dispatch_get_main_queue(), ^
});
打印結(jié)果:
2017-06-15 20:26:05.013 Block[9706:237965] 同步串行隊(duì)列 當(dāng)前線程------><NSThread: 0x618000075640>{number = 1, name = main}
2017-06-15 20:26:05.013 Block[9706:237965] 同步并行隊(duì)列 當(dāng)前線程------><NSThread: 0x618000075640>{number = 1, name = main}
(lldb)
就是因?yàn)槭峭脚砂l(fā)相當(dāng)于同步執(zhí)行task,不會先執(zhí)行后面的task固额。
而同步派發(fā)所在的線程為他所在環(huán)境的線程
示例:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"aaa當(dāng)前線程------>%@", [NSThread currentThread]);
char *sync1 = "sycnQ1";
dispatch_queue_t syncQ1 = dispatch_queue_create(sync1, DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(syncQ1, ^{
NSLog(@"bbb當(dāng)前線程------>%@", [NSThread currentThread]);
});
});
打印結(jié)果:
2017-06-15 20:39:58.953 Block[9833:245664] aaa當(dāng)前線程------><NSThread: 0x6180000770c0>{number = 3, name = (null)}
2017-06-15 20:39:58.953 Block[9833:245664] bbb當(dāng)前線程------><NSThread: 0x6180000770c0>{number = 3, name = (null)}
- 異步派發(fā)眠蚂。當(dāng)走到dispatch_async 時(shí),直接返回斗躏,繼續(xù)執(zhí)行他所在線程的其他代碼任務(wù)逝慧。
示例:
NSLog(@"startstartstartstartstartstartstart");
char *async = "asycnQ";
dispatch_queue_t asyncQ = dispatch_queue_create(async, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(asyncQ, ^{
NSLog(@"異步并行隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"異步主隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"異步全局隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
char *sync = "sycnQ";
dispatch_queue_t syncQ = dispatch_queue_create(sync, DISPATCH_QUEUE_SERIAL);
dispatch_async(syncQ, ^{
NSLog(@"異步串行隊(duì)列 當(dāng)前線程------>%@", [NSThread currentThread]);
});
NSLog(@"endendendendendendendendend");
結(jié)果為:
2017-06-15 21:05:55.498 Block[9937:254941] startstartstartstartstartstartstart
2017-06-15 21:05:55.498 Block[9937:254941] endendendendendendendendend
2017-06-15 21:05:55.498 Block[9937:255124] 異步串行隊(duì)列 當(dāng)前線程------><NSThread: 0x61000007d5c0>{number = 3, name = (null)}
2017-06-15 21:05:55.498 Block[9937:255123] 異步并行隊(duì)列 當(dāng)前線程------><NSThread: 0x6000002622c0>{number = 4, name = (null)}
2017-06-15 21:05:55.498 Block[9937:255127] 異步全局隊(duì)列 當(dāng)前線程------><NSThread: 0x61800007e7c0>{number = 5, name = (null)}
2017-06-15 21:05:55.503 Block[9937:254941] 異步主隊(duì)列 當(dāng)前線程------><NSThread: 0x60000007c740>{number = 1, name = main}
所以異步派發(fā)只在主隊(duì)列不創(chuàng)建線程,在并行(包括全局隊(duì)列)啄糙、和串行(不包括主隊(duì)列)都會創(chuàng)建線程
2.串并行隊(duì)列(DISPATCH_QUEUE_SERIAL笛臣、DISPATCH_QUEUE_CONCURRENT)
- 串行隊(duì)列:按把任務(wù)丟進(jìn)隊(duì)列的順序,同步執(zhí)行(無論是同步派發(fā)還是異步派發(fā):只是影響在哪個(gè)線程執(zhí)行這個(gè)任務(wù))隧饼。
- 并行隊(duì)列:針對同一個(gè)并行隊(duì)列沈堡,加入n個(gè)任務(wù),如果都是異步派發(fā)則會創(chuàng)建n個(gè)線程燕雁,同時(shí)執(zhí)行n個(gè)任務(wù)诞丽。 如果都是同步派發(fā),則會根據(jù)加入task順序執(zhí)行
示例:
char *asyncStr = "asycnQ";
dispatch_queue_t asyncQ = dispatch_queue_create(asyncStr, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(asyncQ, ^{
NSLog(@"異步并行隊(duì)列 線程------>%@ 數(shù)字------>%d", [NSThread currentThread], 1);
});
dispatch_async(asyncQ, ^{
NSLog(@"異步并行隊(duì)列 線程------>%@ 數(shù)字------>%d", [NSThread currentThread], 2);
});
dispatch_sync(asyncQ, ^{
NSLog(@"同步并行隊(duì)列 線程------>%@ 數(shù)字------>%d", [NSThread currentThread], 3);
});
dispatch_async(asyncQ, ^{
NSLog(@"異步并行隊(duì)列 線程------>%@ 數(shù)字------>%d", [NSThread currentThread], 4);
});
dispatch_async(asyncQ, ^{
NSLog(@"異步并行隊(duì)列 線程------>%@ 數(shù)字------>%d", [NSThread currentThread], 5);
});
結(jié)果1:
2017-06-15 22:35:34.854 Block[11257:294626] 異步并行隊(duì)列 線程------><NSThread: 0x61000006adc0>{number = 1, name = main} 數(shù)字------>3
2017-06-15 22:35:34.854 Block[11257:294667] 異步并行隊(duì)列 線程------><NSThread: 0x610000073500>{number = 3, name = (null)} 數(shù)字------>1
2017-06-15 22:35:34.854 Block[11257:294664] 異步并行隊(duì)列 線程------><NSThread: 0x6100000735c0>{number = 4, name = (null)} 數(shù)字------>2
2017-06-15 22:35:34.855 Block[11257:294665] 異步并行隊(duì)列 線程------><NSThread: 0x600000069540>{number = 5, name = (null)} 數(shù)字------>4
2017-06-15 22:35:34.855 Block[11257:294667] 異步并行隊(duì)列 線程------><NSThread: 0x610000073500>{number = 3, name = (null)} 數(shù)字------>5
結(jié)果二:
2017-06-15 22:47:14.167 Block[12836:303509] 同步并行隊(duì)列 線程------><NSThread: 0x608000079c00>{number = 1, name = main} 數(shù)字------>3
2017-06-15 22:47:14.168 Block[12836:303665] 異步并行隊(duì)列 線程------><NSThread: 0x60000007a700>{number = 4, name = (null)} 數(shù)字------>2
2017-06-15 22:47:14.167 Block[12836:303667] 異步并行隊(duì)列 線程------><NSThread: 0x61000007fb40>{number = 3, name = (null)} 數(shù)字------>1
2017-06-15 22:47:14.168 Block[12836:303694] 異步并行隊(duì)列 線程------><NSThread: 0x60000007a400>{number = 5, name = (null)} 數(shù)字------>4
2017-06-15 22:47:14.168 Block[12836:303695] 異步并行隊(duì)列 線程------><NSThread: 0x61800007ea40>{number = 6, name = (null)} 數(shù)字------>5
結(jié)果3:
2017-06-15 22:56:12.379 Block[13913:309705] 異步并行隊(duì)列 線程------><NSThread: 0x61000007e400>{number = 4, name = (null)} 數(shù)字------>2
2017-06-15 22:56:12.379 Block[13913:309596] 同步并行隊(duì)列 線程------><NSThread: 0x60800007ce40>{number = 1, name = main} 數(shù)字------>3
2017-06-15 22:56:12.379 Block[13913:309735] 異步并行隊(duì)列 線程------><NSThread: 0x61800007fa40>{number = 3, name = (null)} 數(shù)字------>1
2017-06-15 22:56:12.380 Block[13913:309705] 異步并行隊(duì)列 線程------><NSThread: 0x61000007e400>{number = 4, name = (null)} 數(shù)字------>4
2017-06-15 22:56:12.380 Block[13913:309703] 異步并行隊(duì)列 線程------><NSThread: 0x61000007e9c0>{number = 5, name = (null)} 數(shù)字------>5
結(jié)果...
每次打印都不一樣拐格,我的理解是當(dāng)執(zhí)行到3時(shí)僧免,因?yàn)?是同步派發(fā),所以會在主線程執(zhí)行任務(wù)禁荒,在執(zhí)行任務(wù)期間猬膨,3之前的1 2 都加入到了asyncQ并行隊(duì)列,也同時(shí)執(zhí)行,可能執(zhí)行完了呛伴,也可能只執(zhí)行了一個(gè),也可能都沒執(zhí)行完 所以前三個(gè)排序 是123 132 213 231 312 321 雖然4 5和1 2都是異步并行隊(duì)列執(zhí)行谒所,但是在同步執(zhí)行時(shí) 4 5 還沒加入隊(duì)列 所以 12 要比45快
GCD_1Demo傳送門