1.常见术语 --- 同步、异步、并发、串行
1.1同步和异步主要影响:能不能开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新的线程的能力
1.2并发和串行主要影响:任务的执行方式
并发:多个任务并发(同是)执行
串行:一个任务执行完毕后在执行下一个任务
2、各种队列的执行效果
|
并发队列 |
手动创建的串行队列 |
主队列 |
同步(sync) |
1.没有开启新线程 2.串行执行任务 |
1.没有开启新线程 2.串行执行任务 |
1.没有开启新线程 2.串行执行任务 |
异步 (async) |
1.有开启新线程2.并发执行任务 |
1.有开启新线程2.串行执行任务 |
1.没有开启新线程 2.串行执行 |
3、使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
4.详细分析实例如下代码
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// dispatch_sync和dispatch_async用来控制是否要开启新的线程
/**
队列的类型,决定了任务的执行方式(并发、串行)
1.并发队列
2.串行队列
3.主队列(也是一个串行队列)
*/
- (void)interview01
{
// 问题:以下代码是在主线程执行的,会不会产生死锁?会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
/*
主线程 主队列
| 任务1 | | viewDidLoad |
| sync任务2 | | 任务2 |
| 任务3 |
队列的特点FIFO 先进先出 viewDidLoad执行结束后 主线程取出任务2执行
任务2 要等待viewDidLoad 结束 导致任务2没法执行 任务3 也无法执行
*/
// dispatch_sync立马在当前线程同步执行任务
}
- (void)interview02
{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
// dispatch_async不要求立马在当前线程同步执行任务
}
- (void)interview03
{
// 问题:以下代码是在主线程执行的,会不会产生死锁?会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ // block0
NSLog(@"执行任务2");
dispatch_sync(queue, ^{ // block1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
/* 只分析 任务block0 任务block1
子线程 串行队列
| 任务1 | | block0 |
| async任务2 | | block1 |
| sync任务3 |
| 任务4 |
| 任务5 |
block0执行完才执行block1
(dispatch_sync(queue, ^{ // block1 ) sync要求在当前线程执行block1
前提条件block0在队列中执行完毕
block0要执行完的前提是 block1 和 任务4要执行完毕 即整个block0 执行结束 block1才能拿出来执行
产生死锁
*/
//block0 和 block1 添加到同一个子线程 串行执行 任务block0拿到队列上执行 包含block1 执行不结束
//block1 执行 等待任务block0执行完毕 死锁
}
- (void)interview04
{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ // 0
NSLog(@"执行任务2");
dispatch_sync(queue2, ^{ // 1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
// 线程[66474:5109860] 执行任务1
// 线程[66474:5109860] 执行任务5
// 线程[66474:5110531] 执行任务2
// 线程[66474:5110531] 执行任务3
// 线程[66474:5110531] 执行任务4
}
- (void)interview05
{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ // 0
NSLog(@"执行任务2");
dispatch_sync(queue, ^{ // 1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
// 线程[66339:5106559] 执行任务1
// 线程[66339:5106559] 执行任务5
// 线程[66339:5107203] 执行任务2
// 线程[66339:5107203] 执行任务3
// 线程[66339:5107203] 执行任务4
}
- (void)viewDidLoad {
[super viewDidLoad];
// [self interview05];
dispatch_queue_t queue1 = dispatch_get_global_queue(0, 0);
dispatch_queue_t queue2 = dispatch_get_global_queue(0, 0);
dispatch_queue_t queue3 = dispatch_queue_create("queu3", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue4 = dispatch_queue_create("queu4", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue5 = dispatch_queue_create("queu5", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"%p %p %p %p %p", queue1, queue2, queue3, queue4, queue5);
//线程[66207:5103539] 0x1053ff080 0x1053ff080 0x600002279080 0x60000227a300 0x600002278b80
//dispatch_get_global_queue 地址相同 全局只有一个全局队列
}
@end
网友评论