GCD中的队列主要有两种,串行队列和并行队列。
串行队列: 调度任务到串行队列,任务将在同一个线程执行,并且顺序执行。
并行队列:调度任务到并行队列, 将开启多个线程,任务执行结束的顺序无法确定。
调度任务到队列的方式也主要有两种,dispatch_sync同步调度和dispatch_async异步调度。
dispatch_sync 任务将在当前线程执行。若同步调度任务到并发队列上,则所有任务在当前线程顺序执行。dispatch_sync任务到串行队列并不一定会死锁。只有将任务同步调度到当前代码所在的队列, 才会死锁。
dispatch_async 如果调度到同一个并行队列上, 将开多个新线程执行,任务乱序执行。
dispatch_async 如果调度到同一个串行队列上,第一次异步调度时会开启一个新线程,后续异步调度会在第一次创建的线程上运行,但肯定会顺序执行。
请看下述代码执行结果:
dispatch_queue_t serialQueue= dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t concurrentQueue=dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t mainQueue=dispatch_get_main_queue();
dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//1:同步调度任务到串行队列中,在主线程下串行执行
for(int i=0;i<10;i++){
dispatch_sync(serialQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//2:同步调度任务到并行队列中,在主线程下串行执行
for(int i=0;i<10;i++){
dispatch_sync(concurrentQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//结果:
//3:同步调度任务到主队列中,锁死
for(int i=0;i<10;i++){
dispatch_sync(mainQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//4:同步调度任务到全局队列中,在主线程下串行执行
for(int i=0;i<10;i++){
dispatch_sync(globalQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//5:异步调度任务到串行队列中,开启一个子线程,所有任务在该线程中串行执行
for(int i=0;i<10;i++){
dispatch_async(serialQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//6:异步调度任务到并行队列中,开启多个子线程,任务并行执行
for(int i=0;i<10;i++){
dispatch_async(concurrentQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//结果:
//7:异步调度任务到主队列中,在主线程中串行执行
for(int i=0;i<10;i++){
dispatch_async(mainQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
//8:异步调度任务到全局队列中,开启多个子线程,在多个子线程中并行执行
for(int i=0;i<10;i++){
dispatch_async(globalQueue, ^{
NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
再看一个更复杂的例子:
- (void)viewDidLoad {
// 默认创建串行队列
dispatch_queue_t queue = dispatch_queue_create("Dan", NULL);
dispatch_sync(queue, ^{
// block 0 //在主线程执行,但不会死锁
NSLog(@"current 0: %@", [NSThread currentThread]);
//在queue的执行体中同步调度另一个任务到queque, 死锁
dispatch_sync(queue, ^{
// block 00
NSLog(@"current 00: %@", [NSThread currentThread]);
});
});
// dispatch_async开启一个子线程
dispatch_async(queue, ^{
NSLog(@"current : %@", [NSThread currentThread]);
dispatch_queue_t serialQueue = dispatch_queue_create("Dan-serial", DISPATCH_QUEUE_SERIAL);
/*同步调度任务到串行队列"Dan-serial", 由于当前代码所在队列为"Dan"这个队列,
*两个队列并不相同,因此不会死锁
*/
dispatch_sync(serialQueue, ^{
// block 1
NSLog(@"current 1: %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
// block 2
NSLog(@"current 2: %@", [NSThread currentThread]);
});
//异步调度到串行队列,开启新线程,但任务顺序执行
dispatch_async(serialQueue, ^{
// block 3
NSLog(@"current 3: %@", [NSThread currentThread]);
});
dispatch_async(serialQueue, ^{
// block 4
NSLog(@"current 4: %@", [NSThread currentThread]);
});
});
}