之前對線程使用的不是太多,今天專門抽時間看了下GCD的線程使用。好記性不如爛筆頭,整理下來方便以后復(fù)習(xí)使用,也與和大家分享一下。第一次寫簡書,水平有限,歡迎大家多多給出建議,互相學(xué)習(xí)。成長的路上,與大家同勉~~~~
下面進(jìn)入正題
需求舉例:有三個任務(wù)需要順序執(zhí)行:任務(wù)1-->任務(wù)2-->任務(wù)3
實(shí)現(xiàn)方式一:(線程組)
①.創(chuàng)建線程組:dispatch_group_t group = dispatch_group_create();
②.創(chuàng)建隊(duì)列:dispatch_queue_t queue = dispatch_queue_create(0, 0);
③.把任務(wù)提交到隊(duì)列中執(zhí)行:dispatch_group_enter(group);
? ????????????????????????????????????????????? dispatch_async(queue, ^{
? ? ? ? ????????????????????????????????????????????????[NSThread sleepForTimeInterval:2];
? ? ? ? ????????????????????????????????????????????????NSLog(@"任務(wù)1執(zhí)行");
? ? ? ????????????????????????????????????????????????? dispatch_group_leave(group);
? ????????????????????????????????????????????? });
????????????????????????????????????????? ? ????dispatch_barrier_async(queue, ^{
? ? ? ????????????????????????????????????????? ? ? ????? NSLog(@"任務(wù)2執(zhí)行");
? ? ????????????????????????????????????? ????? });
④.監(jiān)聽任務(wù)1和任務(wù)二是否執(zhí)行完:?dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
? ? ? ? NSLog(@"任務(wù)3執(zhí)行");
? ? });
打印結(jié)果為:任務(wù)1執(zhí)行---------任務(wù)2執(zhí)行----------任務(wù)3執(zhí)行
劃重點(diǎn):①dispatch_barrier_async(queue, ^{? })方法(我一般叫做柵欄或格柵),該方法的使用要求queue為自己創(chuàng)建的隊(duì)列,不要使用全局隊(duì)列和主隊(duì)列,否則就失去使用柵欄(或者格柵)方法的意義;②dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{? ? })方法可以監(jiān)聽任務(wù)1和任務(wù)2是否完全執(zhí)行完畢,只有前面的任務(wù)執(zhí)行完畢之后才會執(zhí)行任務(wù)3,任務(wù)3最常見的應(yīng)用就是請求完數(shù)據(jù),用于主線程的數(shù)據(jù)刷新或者繼續(xù)進(jìn)行其他操作;③dispatch_group_enter(group)方法和dispatch_group_leave(group)方法是成對使用的,該方法會被線程監(jiān)聽,可以比較安全的保證任務(wù)1和任務(wù)2妥妥的執(zhí)行完畢之后再執(zhí)行任務(wù)3。
實(shí)現(xiàn)方式二:(信號量)
①.創(chuàng)建倆信號量:?dispatch_semaphore_t sem1 = dispatch_semaphore_create(0);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);
②.執(zhí)行任務(wù):
dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);
? ? ? ? NSLog(@"任務(wù)3");
? ? });
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
? ? ? ? NSLog(@"任務(wù)2");
? ? ? ? dispatch_semaphore_signal(sem1);
? ? });
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? NSLog(@"任務(wù)1");
? ? ? ? dispatch_semaphore_signal(sem2);
? ? });
打印結(jié)果為:任務(wù)1執(zhí)行---------任務(wù)2執(zhí)行----------任務(wù)3執(zhí)行
劃重點(diǎn):①dispatch_semaphore_t 創(chuàng)建的信號量sem1和sem2初始值給的都是0;? ? ? ? ? ? ? ? ? ?②第一個異步任務(wù)中dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER)方法會檢查sem1的信號量值是否>0如果>0就會執(zhí)行任務(wù)3,否者就會阻塞線程,任務(wù)3不會執(zhí)行;? ? ? ? ? ?③同理,第二個異步任務(wù)中dispatch_semaphore_wait(sem0, DISPATCH_TIME_FOREVER)方法會檢查sem0的信號量值是否>0如果>0就會執(zhí)行任務(wù)2,否者就會阻塞線程,任務(wù)2不會執(zhí)行;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ④?第三個異步任務(wù)中先執(zhí)行任務(wù)1,然后dispatch_semaphore_signal(sem2)方法會給sem2信號量+1,sem2信號量+1后,第二個異步任務(wù)接收到信號,就會開始執(zhí)行任務(wù)2,然后再執(zhí)行?dispatch_semaphore_signal(sem1)給sem1增加信號量,同時,sem2的信號量會自動-1,變成0,后續(xù)如果不再給sem2增加信號量,就會一直阻塞下去,不再繼續(xù)執(zhí)行;? ? ? ? ? ? ? ? ? ? ? ? ? ? ?⑤sem1信號量+1后,第一個異步任務(wù)接收到信號,就會開始執(zhí)行任務(wù)3,同時,sem1的信號量會自動-1,變成0,后續(xù)如果不再給sem2增加信號量,就會一直阻塞下去,不再繼續(xù)執(zhí)行 。