队列:
在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue。然而,存在于两种Dispatch Queue,一种是要等待上一个执行完,再执行下一个的Serial Dispatch Queue,这叫做串行队列;另一种,则是不需要上一个执行完,就能执行下一个的Concurrent Dispatch Queue,叫做并行队列。
队列:可以理解为存放任务的容器
- 系统标准提供的两个队列
// 全局队列,也是一个并行队列
dispatch_get_global_queue
// 主队列,在主线程中运行,因为主线程只有一个,所以这是一个串行队列
dispatch_get_main_queue - 除此之外,还可以自己生成队列
// 从DISPATCH_QUEUE_SERIAL看出,这是串行队列
dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL)
// 同理,这是一个并行队列
dispatch_queue_create("com.demo.concurrentQueue", DISPATCH_QUEUE_CONCURRENT)
同步与异步
串行与并行针对的是队列,而同步与异步,针对的则是线程。最大的区别在于,同步线程要阻塞当前线程,必须要等待同步线程中的任务执行完,返回以后,才能继续执行下一任务;而异步线程则是不用等待。
同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。
GCD跑几个方法 结果一目了然
/**
* async -- 并发队列(最常用)
* 会不会创建线程:会,一般同时开多条
* 任务的执行方式:并发执行
*/
- (void)asyncGlobalQueue
{
// 获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任务 添加 全局队列 中去 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync -- 并发队列
* 会不会创建线程:不会,当前线程中执行
* 任务的执行方式:串行执行
*/
- (void)syncGlobalQueue
{
// 获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任务 添加 全局队列 中去 异步 执行
dispatch_sync(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* async -- 串行队列(有时候用)
* 会不会创建线程:会,一般只开1条线程
* 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
*/
- (void)asyncSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.将任务添加到串行队列中 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync 同步执行 -- 串行队列
* 会不会创建线程:不会,当前线程中执行
* 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
*/
- (void)syncSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.将任务添加到串行队列中 异步 执行
dispatch_sync(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* async 异步执行 -- 主队列串行队列
* 会不会创建线程:不会,当前线程中执行
* 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
*/
- (void)asyncMainSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.将任务添加到串行队列中 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync 同步执行 -- 主队列串行队列
* 线程死锁
*/
- (void)syncMainSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.将任务添加到串行队列中 异步 执行
dispatch_sync(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
线程死锁
- (void)syncSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.将任务添加到串行队列中 异步 执行
dispatch_sync(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
//
dispatch_sync(queue, ^{
NSLog(@"-----XXX下载图片1XX---%@", [NSThread currentThread]);
});
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
http://www.jianshu.com/p/c0e2d96a238e
要求请求A和请求B都都完成拿到结果,再执行C操作。
// *** 利用队列组 ****//
- (void)userGroupMethod
{
// 创建队列组
dispatch_group_t myGroup = dispatch_group_create();
// 创建并发队列
dispatch_queue_t myQueue = dispatch_queue_create(0, 0);
// 使用函数添加任务(所有任务都是并发执行)
/**
* 任务A
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 请求A
if (success) {
// 请求成功
dispatch_group_leave(myGroup);
}else{
// 失败
dispatch_group_leave(myGroup);
}
});
/**
* 任务B
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 请求B
if (success) {
// 请求成功
dispatch_group_leave(myGroup);
}else{
// 失败
dispatch_group_leave(myGroup);
}
});
// A,B执行完毕,不论成功失败。只要执行完毕就执行下方代码
dispatch_group_notify(myGroup, myQueue, ^{
// 执行C操作。注意刷新UI等需要回到主线程。
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新等操作。
});
});
}