iOS中的同步異步、串行並行做了較為詳細的講解。在之後的幾篇GCD實踐的博客中對GCD的使用也有較為詳細的實現。但是我們要注意的是,那裡用到的GCD是別人對蘋果的原生GCD接口封裝後的使用,雖然用起來更為方便,但是為了有全面的學習,我還是推薦去用蘋果原生的GCD。
只要是同步執行的任務,都會在當前線程執行,不會另開線程。 只要是異步任務執行的任務,都會另開線程,在別的線程執行。 同步操作會阻塞當前線程,直到block中的任務執行完畢,然後當前線程才會繼續往下執行。(block在主線程中執行) 異步操作,當前線程會直接往下執行,不會阻塞當前線程。 (因為block在新線程中執行) 串行隊列:一次只執行一個線程。 並行隊列:一次可以執行多個線程。
(1)自己創建一個並發隊列,並同步執行
//dispatch_queue_t 也可以自己定義,如果要自定義,可以用dispatch_queue_create方法。 //當然也可以使用系統提供的global_queue,main_queue dispatch_queue_t syncQueue = dispatch_queue_create("my.concurrent.syncQueue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); dispatch_sync(syncQueue, ^{ NSLog(@"2"); [NSThread sleepForTimeInterval:3]; NSLog(@"3"); }); NSLog(@"4"); dispatch_release(syncQueue);//最好需要釋放建議該隊列使用完後,進行release。
(2)自己創建一個並發隊列,異步執行
dispatch_queue_t asyncQueue = dispatch_queue_create("my.concurrent.asyncQueue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); dispatch_async(asyncQueue, ^{ NSLog(@"2"); [NSThread sleepForTimeInterval:3]; NSLog(@"3"); }); NSLog(@"4"); dispatch_release(asyncQueue);
(3)自己創建一個串行隊列,同步執行
dispatch_queue_t syncQueue = dispatch_queue_create("my.serial.syncQueue", DISPATCH_QUEUE_SERIAL); NSLog(@"1"); dispatch_sync(syncQueue, ^{ NSLog(@"2"); [NSThread sleepForTimeInterval:3]; NSLog(@"3"); }); NSLog(@"4"); dispatch_release(syncQueue);
(4)自己創建一個串行隊列,異步執行
dispatch_queue_t asyncQueue = dispatch_queue_create("my.serial.asyncQueue", DISPATCH_QUEUE_SERIAL); NSLog(@"1"); //第一個參數是指定了一個GCD隊列,第二個參數是分配事務到該隊列。 dispatch_async(asyncQueue, ^{ NSLog(@"2"); [NSThread sleepForTimeInterval:3]; NSLog(@"3"); }); NSLog(@"4"); dispatch_release(asyncQueue);
(5)關於系統提供的線程
dispatch_global_queue :並行隊列
dispatch_private_queue:串行隊列
dispatch_main_queue:主線程
以下代碼是異步執行耗時操作,並更新UI的代碼:
dispatch_async(dispatch_get_global_queue(0, 0), ^{ //進入另一個線程,處理耗時的代碼塊 dispatch_async(dispatch_get_main_queue(), ^{ //返回主線程刷新 }); });
(6)一次性執行某個操作,並在應用生命周期內僅執行一次
//在該應用聲明周期內,下面的代碼只會被執行一次。並且是線程安全的。 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"僅會被執行一次"); });
(7)線程組,是一種同步機制,可以讓某些線程先執行,某些線程最後執行,以控制線程的執行順序。
//GCD的高級用法 線程組;線程組和信號量機制都可以實現隊列的同步。 __block int i; __block int j; dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ i = 1; }); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ j = 2; }); dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{ NSLog(@"%d",i+j); });
NSLog(@"1"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"延遲3s執行這裡"); });
(9)信號量,同步機制,控制線程執行流程。可以和操作系統中的信號量聯系起來理解。
//信號量 /** * 創建一個信號量。參數指定信號量的起始值。這個數字是你可以訪問的信號量,不需要先去增加它的數量(增加信號量也叫作發射信號量)。 初始value = 0時,信號量--,小於0,wait線程阻塞。然後執行signal,信號量++,激活wait線程。 * */ dispatch_semaphore_t sema = dispatch_semaphore_create(0); dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); NSLog(@"chen"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"yu"); dispatch_semaphore_signal(sema); });