二、任务、队列之间的嵌套

2018-09-13  本文已影响0人  人间四月天_Andy

此文章只做学习笔记之用,如有错误,欢迎留言批评指正!!!


 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.    先输出begin 

2.    接下来碰到一个同步函数(block1),不会开辟线程,阻塞当前线程,打印 任务1

3.    然后碰到异步函数(block2)会开辟新线程,所以会把这个异步串行队列函数(也就是block2)放到子线程中去运行,因为是串行队列,所以在同步串行队列函数(也就是block1)运行完之前block2任务不会执行,因此会先打印 任务3

4.    block1 执行完成后,可能会打印end 也可能会打印任务2 这两个的打印顺序是不可控的

结果1

在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前边

上一篇下一篇

猜你喜欢

热点阅读