二、任务、队列之间的嵌套
此文章只做学习笔记之用,如有错误,欢迎留言批评指正!!!
GCD之任务、队列之间的相互嵌套
注意:
同步、异步:针对的是线程
串行、并行:针对的是队列
一条线程同一时间只能执行一个任务,同步的话,不会开辟线程,所以任务只会在主线程里边进行,因此,同步任务里边,不管是串行队列还是并行队列,都只能是一个任务完成之后,才会执行下个任务。
一、 同步并发嵌套异步
同步并发嵌套异步1 同步并发嵌套异步2添加耗时操作 输出结果分析:
1. 先输出begin (这个毋庸置疑)
2. 接下来,是一个同步并发任务(简称block1),而同步任务会阻塞当前线程,所以只有当block里边的任务执行完之后才会执行 任务end 所以end 排在最后边
3. block1中有包含三个小任务 任务1、block2、任务3,而block2中只有一个任务2
4. block1中任务的执行顺序肯定是先输出任务1,这个就不啰嗦了。接下来是block2,而block2 是一个异步的,所以不会阻塞当前线程,由于是异步的,所以可能会开辟一条新线程运行任务2
5. 因为异步没有阻塞当前线程,所以block2这个任务有没有完成不会影响任务3的执行,因此任务3 可能会在任务2之前输出。当然也有可能任务2在前,任务3在后。
6. 接下来上图,在任务3之前模拟一个耗时操作
结论:begin 任务1 任务3 任务2 end 或者 begin 任务1 任务2 任务3 end
二、 同步并发嵌套同步
同步并发嵌套同步分析:应为都是同步,所以每个任务都不会开辟新线程 都会阻塞当前线程,任务一个接一个执行,所以无论是否添加耗时操作,结果都一样
结论:输出结果就是 begin ->任务1 ->任务2 ->任务3 ->end
三、同步串行嵌套异步
同步串行嵌套异步队列是串行队列
同步串行队列函数–>block1
异步串行队列函数–>block2
结果1分析:
1. 先输出begin
2. 接下来碰到一个同步函数(block1),不会开辟线程,阻塞当前线程,打印 任务1
3. 然后碰到异步函数(block2)会开辟新线程,所以会把这个异步串行队列函数(也就是block2)放到子线程中去运行,因为是串行队列,所以在同步串行队列函数(也就是block1)运行完之前block2任务不会执行,因此会先打印 任务3
4. block1 执行完成后,可能会打印end 也可能会打印任务2 这两个的打印顺序是不可控的
在end之前添加一个耗时操作,则打印结果是这样的:
结果2四、 同步串行嵌套同步
异步并发嵌套异步运行结果:
运行结果很明显:死锁,也就是两个任务相互等待(block2 等待block1 完成,而block1 又在等待block2 完成)
五、 异步串行嵌套异步
异步串行嵌套异步1 异步串行嵌套异步2分析:
1. begin 先输出
2. 接下来是一个异步串行队列函数(block1),由于是异步的,不会阻塞当前线程,所以block1 和end 的输出顺序就是不可控的,同理block2 和end的输出顺序也是不可控的。
3. 因为是串行队列,任务会一个一个执行,任务2的输出一定是在任务3后边,即使任务3前边添加了耗时操作
结论:
由于是异步的所以输出顺序就会变得不可控,下面列出集中输出顺序,以供参考:
①. begin – 任务1 – 任务3 – end – 任务2
②. begin – end – 任务1 – 任务3 – 任务2
③. begin – 任务1 – 任务3 – 任务2 – end
④. begin – 任务1 – end – 任务3 – 任务2
六、 异步串行嵌套同步(死锁)
异步串行嵌套同步(死锁)分析:
1. begin
2. 接下来遇到异步函数,将任务1、同步线程(block2)、任务3 添加到了串行队列中。由于是异步线程,所以end 可以不必等待直接block1中的任务完成
3. 所以 end 和任务1 的输出位置就是不可控的
4. 任务1 输出之后,遇到同步线程,将任务2添加到串行队列中
5. 由于任务3 比任务2 先添加到串行队列,所以,任务2 要等到任务3完成之后,才能执行。但是任务2是所在的同步线程会发生阻塞,所以任务3 又必须等任务2执行完成之后再执行,因此,就会陷入到无限等待中,造成死锁。
相关链接:http://ios.jobbole.com/82622/(此文介绍的比较通俗易懂,没看明白的小伙伴可以查看此篇文章)
七、 异步并发嵌套同步
异步并发嵌套同步分析:
1. begin ,接下来是遇到一个异步并发队列,所以end 的输出则不受影响
2. 在block1中 一次添加了任务1 、同步并发队列(block2)、任务3
3. 然后输出任务1 接下来遇到一个同步线程,将任务2添加到并发队列中,由于同步会阻塞当前线程,所以任务3 必须等到任务2输出之后,才能输出,即使在任务2里边添加耗时操作,任务3的输出一定是在任务2之后
4. end的输出顺序不可控
八、 异步并发嵌套异步
异步并发嵌套异步分析:
1. begin,接下来是一个异步
2. 所以end 的输出顺序不可控
3. 由于都是异步的并且都是并发队列,所以任务1、任务2、任务3的顺序也都是不可控的,但是任务1肯定是在任务2、任务3前边