1、串行队列
dispatch_queue_t queue1 = dispatch_queue_create("com.queue", DISPATCH_QUEUE_CONCURRENT);
2、并行队列
dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_SERIAL);
3、dispatch_sync : 同步队列
同步执行方式,也就是使用dispatch_sync()来执行队列不会开辟新的线程,会在当前线程中执行任务。如果当前线程是主线程的话,那么就会阻塞主线程,因为主线程被阻塞了,就会会造成UI卡死的现象。因为同步执行是在当前线程中来执行的任务,也就是说现在可以供队列使用的线程只有一个,所以串行队列与并行队列使用同步执行的结果是一样的,都必须等到上一个任务出队列并执行完毕后才可以去执行下一个任务。我们可以使用同步执行的这个特点来为一些代码块加同步锁。下方就是上面代码以及执行结果的描述图。
4、dispatch_async:异步执行
在GCD中使用dispatch_async()函数来进行异步执行,dispatch_async()函数的参数与dispatch_sync()函数的参数一致。只不过是dispatch_async()异步执行不会在当前线程中执行,它会开辟新的线程,所以异步执行不会阻塞当前线程。
串行队列的异步执行:
一个串行队列如果使用异步执行的话,会开辟一个新的线程2来执行队列中的Block任务。在新开辟的线程中依然是FIFO, 并且执行顺序是等待上一个任务执行完毕后才开始执行下一个任务。
并行队列的异步执行:
并行队列异步执行时会开辟多个新的线程来执行队列中的任务,队列中的任务出队列的顺序仍然是FIFO,只不过是不需要等到前面的任务执行完而已,只要是有空余线程可以使用就可以按FIFO的顺序出队列进行执行
5、设置队列的优先级
dispatch_queue_t queue1 = dispatch_queue_create("com.queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t curQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);//设置当前的队列优先级
dispatch_set_target_queue(queue1, curQueue);//将当前队列的优先级 赋值给创建的队列的优先级
6、任务组dispatch_group
dispatch_group_t group1 = dispatch_group_create();
for(NSInteger i=0;i<3;i++){
dispatch_group_async(group1, queue1, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"当前线程%@",[NSThread currentThread]);
});
}
dispatch_group_notify(group1, queue1, ^{
NSLog(@"任务组测试完毕");
});
打印结果:
2017-03-13 14:26:37.881 CLLocationTest[3787:100628] 当前线程{number = 3, name = (null)}
2017-03-13 14:26:40.953 CLLocationTest[3787:100628] 当前线程{number = 3, name = (null)}
2017-03-13 14:26:40.953 CLLocationTest[3787:100628] 当前线程{number = 3, name = (null)}
分析:queue1是串行队列,所有的任务会在一个的线程中顺序执行,并且三个任务执行完成后,发出通知,任务完毕
如果将queue1 改成DISPATCH_QUEUE_CONCURRENT,所有的任务会分配到别的线程,相当于同步一起执行,完成后发出通知,任务完毕
7、任务栅栏:dispatch_barrier_async 设置任务的执行顺序
for(int i=0;i<2;i++){
dispatch_async(queue1, ^{
int aa = arc4random()%4;
[NSThread sleepForTimeInterval:aa];
NSLog(@"当前线程%@,时间%d",[NSThread currentThread],aa);
});
}
dispatch_barrier_async(queue1, ^{
NSLog(@"栅栏线程:%@",[NSThread currentThread]);
});
for(int i=0;i<2;i++){
dispatch_async(queue1, ^{
int aa = arc4random()%4;
[NSThread sleepForTimeInterval:aa];
NSLog(@"当前线程%@,时间%d",[NSThread currentThread],aa);
});
}
下图画的就是栅栏工作的方式,需要注意的是队列中的第一批任务中的最后一个任务与栅栏中的任务已经第二批第一个任务是用一个线程来执行的。这就是为什么栅栏能进行任务隔离的根本了。从下方的图中我们不难发现,任务1.3、栅栏任务、任务2.1在线程5中是同步执行的。具体请看下图。