讲解GCD的资料看了好多,但都没有解决心中的疑惑:
1.主队列只有一个线程,那么同步和异步执行有什么区别?同步主线程会造成线程死锁,异步不会,为什么呢?
2.同步执行串行队列和同步执行并行队列,有什么区别?同步执行,是在当前线程中执行队列中的任务,就意味着任务都在一条线程中执行,不可能多任务同时执行啊。
3.在主线程中同步执行串行队列,为什么就不造成线程死锁呢?
有疑不解,如鲠在喉。有疑惑就代表学得不到位,概念理解不够。因此,我开始重头学习GCD,理清这些基础概念。
有4个术语比较容易混淆:同步、异步、并发、串行
同步和异步决定了要不要开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力
并发和串行决定了任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
组合一下:
- 同步执行串行队列
- 同步执行并发队列
- 异步执行串行队列
- 异步执行并发队列
- 同步执行主队列
- 异步执行主队列
我加入了主队列(只有一条线程的串行队列),是因为它和一般的串行队列有些区别。下面我就对这6种情况逐个分析。
1.同步执行串行队列:在当前线程中,逐一执行队列中的任务。
2.同步执行并发队列:同1
3.异步执行串行队列:开启一条新线程,逐一执行队列中的任务。
4.异步执行并发队列:开启多条线程,同时执行队列中的多个任务。
先理清这四种情况的嵌套执行,在讲主线的两种情况。
下面就是大堆代码了,对照代码和打印结果进行思考,看有没有自己觉得解释不通的。
demo地址:https://github.com/jiliuliu/FoundationOC
int main(int argc, const char * argv[]) { @autoreleasepool { dispatch_queue_t backgroundSerialQueue = dispatch_queue_create("backgroundSerialQueue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL); dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT); //避开主线程,单独开启一个线程做测试 dispatch_async(backgroundSerialQueue, ^{ NSLog(@"%@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)1"); }); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)2"); }); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)3"); }); NSLog(@"************************"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)1"); }); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)2"); }); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)3"); }); }); } NSLog(@"----exit----"); return 0; }
打印结果:
----exit---- <NSThread: 0x10064f1b0>{number = 2, name = (null)}
感觉和预想的那里不对,于是修改下:
int main(int argc, const char * argv[]) { @autoreleasepool { dispatch_queue_t backgroundSerialQueue = dispatch_queue_create("backgroundSerialQueue", DISPATCH_QUEUE_SERIAL); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL); dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT); //避开主线程,单独开启一个线程做测试 dispatch_async(backgroundSerialQueue, ^{ NSLog(@"%@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)1"); }); NSLog(@"dispatch_sync(serialQueue)1--"); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)2"); }); NSLog(@"dispatch_sync(serialQueue)2--"); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)3"); }); NSLog(@"dispatch_sync(serialQueue)3--"); NSLog(@"************************"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)1"); }); NSLog(@"ispatch_sync(concurrentQueue)1--"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)2"); }); NSLog(@"ispatch_sync(concurrentQueue)2--"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)3"); }); NSLog(@"ispatch_sync(concurrentQueue)3--"); dispatch_barrier_sync(serialQueue, ^{ dispatch_semaphore_signal(semaphore); }); dispatch_barrier_sync(concurrentQueue, ^{ dispatch_semaphore_signal(semaphore); }); }); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); } NSLog(@"----exit----"); return 0; }
打印结果:
<NSThread: 0x100600170>{number = 2, name = (null)} dispatch_sync(serialQueue)1 dispatch_sync(serialQueue)1-- dispatch_sync(serialQueue)2 dispatch_sync(serialQueue)2-- dispatch_sync(serialQueue)3 dispatch_sync(serialQueue)3-- ************************ dispatch_sync(concurrentQueue)1 ispatch_sync(concurrentQueue)1-- dispatch_sync(concurrentQueue)2 ispatch_sync(concurrentQueue)2-- dispatch_sync(concurrentQueue)3 ispatch_sync(concurrentQueue)3-- ----exit----
对,就应该是这样的。
5.同步执行主队列:
6.异步执行主队列: