GCD队列理解
先抛总结点:
1.并行队列要并行执行,其实也是通过开辟多个子线程实现的;那么当并行队列遇到没法开辟多个子线程,那么他就没法达到并行的目的,例如dispatch_sync(concurrentQueue
,理解了这点,这块知识就很好记住了
2.dispatch_async
会开辟一个线程执行,dispatch_sync
当前线程执行
3.dispatch_get_main_queue()上的任务肯定是在主线程上跑
再看下面的详述的好理解了
/// 在主线程执行这个,这时候主队里有一个任务1,就是这一块
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
然后这个里面又把block任务,也就是NSLog(@"1");当成任务2吧,再放到主队列
那么这时候主队列就有任务1和任务2
任务1执行完的定义
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
这一块都执行完,也就是NSLog(@"1")也得执行完
所以这时候任务2(NSLog(@"1"))要执行,又得等任务1执行完,所以就死锁了
并行队列和串行队里的任务在哪个线程执行,是取决于dispatch_async
和dispatch_sync
的,
dispatch_async
会开辟一个线程执行,dispatch_sync
当前线程执行
dispatch_async(concurrentQueue
是开辟多个子线程执行的,并且block
是并行的
dispatch_async(serialQueue,
是开辟一个子线程执行,而且block
都是有序执行的
所以串行队列、并行队列和dispatch_async
结合,首先任务一定是在子线程执行
队列的影响只是,并行队列会开辟多个子线程,达到并行的目的;串行队列就按照dispatch_async
的来,就在新开辟的这个子线程上搞,达到串行的目的
dispatch_async(dispatch_get_main_queue()
是在主线程中执行的,并且block
的串行的,也就是说,主队列的任务一定是在主线程上跑
dispatch_sync(concurrentQueue
和dispatch_sync(serialQueue
都是在当前线程上串行的执行,因为dispatch_sync
不会去开辟新的线程,所以就算是dispatch_sync(concurrentQueue
也不会并行执行
队列有三种:dispatch_get_main_queue,dispatch_queue_create,dispatch_get_global_queue
测试下,加深理解
// 并行队列 异步+同步
- (void)test1
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
// 异步开辟一个子线程
dispatch_async(queue, ^{
NSLog(@"2");
// 同步,卡住当前线程,知道3输出,所以3->4
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 并行队列 异步+异步
- (void)test2
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
// 异步开辟一个子线程
dispatch_async(queue, ^{
NSLog(@"2");
// 再开辟一个子线程,所以先4再3
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 串行队列 异步+异步
- (void)test3
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
// 开辟一个子线程
dispatch_async(queue, ^{
NSLog(@"2");
// 再开辟一个子线程,首先这里要明白,2,3,4算是串行队列中的一个任务,因为3是新开了一个子线程,又不会卡住,所以输出2,4这个任务就算完成了,然后新开的这个子线程再执行3
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 串行队列 异步+同步
- (void)test4
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
// 开辟一个子线程
dispatch_async(queue, ^{
NSLog(@"2");
// 2,3,4是同一个任务,sync不会开辟线程,所以他又将3加入到串行队列中,这时候队列第一个任务是2,3,4,第二个任务是3,因为他得把2,3,4执行完才会轮到第二个任务,问题是他要执行完,输出这个3,这个3是在第二个任务里面的,所以死锁了
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}