「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
队列的创建
创建自定义并发队列和串行队列
//并行队列
dispatch_queue_t queue = dispatch_queue_create("com.gcd.queue", DISPATCH_QUEUE_CONCURRENT);
//串行队列
dispatch_queue_t queue = dispatch_queue_create("com.gcd.queue", NULL);
参数1:队列名称,命名规则为FQDN,应用名称ID的倒序 + queue名字
参数2:队列类型,设置为 NULL
,默认创建串行队列(DISPATCH_QUEUE_SERIAL
)。创建并行队列将参数设置为 DISPATCH_QUEUE_CONCURRENT
获得全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
参数1:优先级
DISPATCH_QUEUE_PRIORITY_HIGH//高优先级
DISPATCH_QUEUE_PRIORITY_DEFAULT//默认优先级
DISPATCH_QUEUE_PRIORITY_LOW//低优先级
DISPATCH_QUEUE_PRIORITY_BACKGROUND//后台优先级
参数2:目前没有意义,官方文档提示传0)
获得全局主队列(特殊的串行队列)
- 放在主队列中的任务,都会放在主线程中执行
- 主队列的实质上就是一个普通的串行队列,只是因为默认情况下,当前代码是放在主队列中的,然后主队列中的代码,有都会放到主线程中去执行
dispatch_queue_t queue = dispatch_get_main_queue();
任务和队列不同组合方式的区别
并发队列 + 异步函数
- 可以开启多个线程,任务同时执行(异步函数具备开启新线程)
示例:
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//异步函数
dispatch_async(concurrentQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--1--%@",[NSThread currentThread]);
}
});
//异步函数
dispatch_async(concurrentQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--2--%@",[NSThread currentThread]);
}
});
log:
并发队列 + 同步函数
- 在当前线程中执行任务,不会开启新线程,执行完一个任务,再执行下一个任务
- 按顺序执行的原因:虽然并发队列可以开启多个线程,并且同时执行多个任务,但是同步函数不具备开启新线程的能力,所以也就不存在并发。因此任务只能一个接一个按顺序执行,不能同时被执行。
示例:
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//同步函数
dispatch_sync(concurrentQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--1--%@",[NSThread currentThread]);
}
});
//同步函数
dispatch_sync(concurrentQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--2--%@",[NSThread currentThread]);
}
});
log:
串行队列 + 异步函数
- 会开新线程,任务是串行的,执行完一个再执行下一个(异步函数具备开启新线程)
示例:
dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.serialQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//异步函数
dispatch_async(serialQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--1--%@",[NSThread currentThread]);
}
});
//异步函数
dispatch_async(serialQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--2--%@",[NSThread currentThread]);
}
});
log:
串行队列 + 同步函数
- 所有任务都是在当前线程(主线程)中执行的,并没有开启新的线程(同步函数不具备开启新线程)
示例:
dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.serialQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//同步函数
dispatch_sync(serialQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--1--%@",[NSThread currentThread]);
}
});
//同步函数
dispatch_sync(serialQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--2--%@",[NSThread currentThread]);
}
});
log:
主队列 + 异步函数
- 所有任务都是在当前线程(主线程)中执行的,并没有开启新的线程(虽然异步执行具备开启线程的能力,但因为是主队列,所以所有任务都在主线程中)
示例:
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//异步函数
dispatch_async(mainQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--1--%@",[NSThread currentThread]);
}
});
//异步函数
dispatch_async(mainQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"异步函数--2--%@",[NSThread currentThread]);
}
});
log:
主队列 + 同步函数
主队列中加同步任务和主线程本身的任务两者之间相互等待,阻塞了主队列,最终造成了主队列所在的线程(主线程)死锁问题
示例:
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSLog(@"当前线程--0--%@",[NSThread currentThread]);
//同步函数
dispatch_sync(mainQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--1--%@",[NSThread currentThread]);
}
});
//同步函数
dispatch_sync(mainQueue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"同步函数--2--%@",[NSThread currentThread]);
}
});
log:
各种队列的执行效果
类型 | 并发队列 | 串行队列 | 主队列 |
---|---|---|---|
同步(sync) | 不会开新线程 串行执行任务 | 不会开新线程 串行执行任务 | 死锁卡住不执行 |
异步(async) | 会开新线程 并行执行任务 | 会开新线程 串行执行任务 | 不会开新线程 串行执行任务 |