- 串行队列 DISPATCH_QUEUE_SERIAL
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_SERIAL);
- 并发队列 DISPATCH_QUEUE_CONCURRENT
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_CONCURRENT);
- 全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- 主队列
dispatch_queue_t queue = dispatch_get_main_queue();
- 同步任务
dispatch_sync(queue, ^{
// 同步任务
})
- 异步任务
dispatch_async(queue, ^{
// 异步任务
})
几种执行方式
- 同步任务 + 并发队列
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
#打印
1 - <_NSMainThread: 0x600001b6c800>{number = 1, name = main}
2 - <_NSMainThread: 0x600001b6c800>{number = 1, name = main}
3 - <_NSMainThread: 0x600001b6c800>{number = 1, name = main}
结论: 虽然是并发队列,但是由于是同步任务,不会开启新的线程,只能依次按顺序执行
- 异步任务 + 并发队列
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
#打印
2 - <NSThread: 0x60000024c140>{number = 3, name = (null)}
1 - <NSThread: 0x60000021cd80>{number = 5, name = (null)}
3 - <NSThread: 0x600000250340>{number = 6, name = (null)}
结论: 开辟新的线程,没有安顺序执行
- 同步任务 + 串行队列
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
#打印
1 - <_NSMainThread: 0x600000654880>{number = 1, name = main}
2 - <_NSMainThread: 0x600000654880>{number = 1, name = main}
3 - <_NSMainThread: 0x600000654880>{number = 1, name = main}
结论: 没有开辟线程,按顺序在主线程执行
- 异步任务 + 串行队列
dispatch_queue_t queue = dispatch_queue_create("task.serial.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
#打印
1 - <NSThread: 0x60000176e980>{number = 4, name = (null)}
2 - <NSThread: 0x60000176e980>{number = 4, name = (null)}
3 - <NSThread: 0x60000176e980>{number = 4, name = (null)}
结论: 开辟新的线程,按顺序执行
- 同步执行 + 主队列
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
⚠️ 如果在主线程中 同步执行+住队列,会直接锁死;在其他线程中则会到主线程中顺序执行
-(void)test
{
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:NULL];
}
-(void)run
{
NSLog(@"0 - %@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
}
#打印
0 - <NSThread: 0x600003ccc8c0>{number = 7, name = (null)}
1 - <_NSMainThread: 0x600003cd4800>{number = 1, name = main}
2 - <_NSMainThread: 0x600003cd4800>{number = 1, name = main}
3 - <_NSMainThread: 0x600003cd4800>{number = 1, name = main}
- 异步执行 + 主队列
NSLog(@"%@ -- begin",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 - %@",[NSThread currentThread]);
});
NSLog(@"%@ -- end",[NSThread currentThread]);
#打印
<_NSMainThread: 0x6000033b8800>{number = 1, name = main} -- begin
<_NSMainThread: 0x6000033b8800>{number = 1, name = main} -- end
1 - <_NSMainThread: 0x6000033b8800>{number = 1, name = main}
2 - <_NSMainThread: 0x6000033b8800>{number = 1, name = main}
3 - <_NSMainThread: 0x6000033b8800>{number = 1, name = main}
结论: 没有开辟线程,异步任务在主线程中按顺序执行
- GCD线程间通信
// 全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"%@",[NSThread currentThread]);
dispatch_sync(mainQueue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
});
GCD的一些其他方法
- 栅栏任务
dispatch_queue_t queue = dispatch_queue_create("barrier.queue.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务1 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务2 - %@",[NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"栅栏任务 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务3 - %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务4 - %@",[NSThread currentThread]);
});
#打印
任务2 - <NSThread: 0x600003828bc0>{number = 8, name = (null)}
任务1 - <NSThread: 0x600003878880>{number = 4, name = (null)}
栅栏任务 - <NSThread: 0x600003878880>{number = 4, name = (null)}
任务3 - <NSThread: 0x600003878880>{number = 4, name = (null)}
任务4 - <NSThread: 0x600003828bc0>{number = 8, name = (null)}
结论: 栅栏任务把一个并发异步队列分成两段,在栅栏任务之前的先执行,然后栅栏任务在执行,最后在执行栅栏任务后面的任务.
- 延时执行
NSLog(@"begin - %@",[NSThread currentThread]);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
NSLog(@"after - %@",[NSThread currentThread]);
});
- 只执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"任务 - %@",[NSThread currentThread]);
});
- 快速迭代
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"begin - %@",[NSThread currentThread]);
dispatch_apply(6, queue, ^(size_t iteration) {
NSLog(@"%zu - %@",iteration,[NSThread currentThread]);
});
NSLog(@"end - %@",[NSThread currentThread]);
#打印
begin - <_NSMainThread: 0x60000191c800>{number = 1, name = main}
0 - <_NSMainThread: 0x60000191c800>{number = 1, name = main}
1 - <NSThread: 0x600001906f80>{number = 7, name = (null)}
2 - <NSThread: 0x600001944080>{number = 6, name = (null)}
3 - <_NSMainThread: 0x60000191c800>{number = 1, name = main}
4 - <NSThread: 0x600001906f80>{number = 7, name = (null)}
5 - <NSThread: 0x600001944080>{number = 6, name = (null)}
end - <_NSMainThread: 0x60000191c800>{number = 1, name = main}
结论: 类似于遍历, 在begin和end之间执行,会开辟新线程执行任务,效率会加快
- dispatch_group_t
NSLog(@"begin - %@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务1 - %@",[NSThread currentThread]);
});
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务2 - %@",[NSThread currentThread]);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务3 - %@",[NSThread currentThread]);
NSLog(@"end - %@",[NSThread currentThread]);
});
#打印
begin - <_NSMainThread: 0x600003f38880>{number = 1, name = main}
任务1 - <NSThread: 0x600003f70d00>{number = 6, name = (null)}
任务2 - <NSThread: 0x600003f7d440>{number = 5, name = (null)}
任务3 - <_NSMainThread: 0x600003f38880>{number = 1, name = main}
end - <_NSMainThread: 0x600003f38880>{number = 1, name = main}
结论: 多个异步并发队列执行结束后在执行主线程任务
- dispatch_group_wait
NSLog(@"begin - %@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务1 - %@",[NSThread currentThread]);
});
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务2 - %@",[NSThread currentThread]);
});
// 等待上面任务完成后在执行下面任务
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"任务3 - %@",[NSThread currentThread]);
NSLog(@"end - %@",[NSThread currentThread]);
#打印
begin - <_NSMainThread: 0x60000302c880>{number = 1, name = main}
任务1 - <NSThread: 0x60000303c1c0>{number = 6, name = (null)}
任务2 - <NSThread: 0x60000307c600>{number = 7, name = (null)}
任务3 - <_NSMainThread: 0x60000302c880>{number = 1, name = main}
end - <_NSMainThread: 0x60000302c880>{number = 1, name = main}
结论: dispatch_group_wait 相当于阻塞当前线程,等之前的任务完成后在走下面的任务
- dispatch_group_enter ,dispatch_group_leave
NSLog(@"begin - %@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_async(globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务1 - %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(globalQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务2 - %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务3 - %@",[NSThread currentThread]);
NSLog(@"end - %@",[NSThread currentThread]);
});
begin - <_NSMainThread: 0x600000b4c800>{number = 1, name = main}
任务2 - <NSThread: 0x600000b090c0>{number = 3, name = (null)}
任务1 - <NSThread: 0x600000b101c0>{number = 5, name = (null)}
任务3 - <_NSMainThread: 0x600000b4c800>{number = 1, name = main}
end - <_NSMainThread: 0x600000b4c800>{number = 1, name = main}
结论: dispatch_group_notify 之前的任务完成后在执行dispatch_group_notify的任务