本文力求做到全网将GCD队列和任务各种组合讲得最通俗易懂的文章,如果做不到,那你们来打我啊!
文章参考内容:iOS 多线程:『GCD』详尽总结
任务和队列
任务和队列是GCD中的核心概念。
任务就是我们要执行的代码,分为『同步执行』和『异步执行』。
- 同步执行:将任务在指定队列中依次执行,当前任务必须等前面一个添加的任务执行完成后才能执行,并且所有的任务都在同一线程;
- 异步执行:将任务添加到指定队列中执行,且无需等待可以立即执行,此任务可以添加到新的线程,但并不一定开启新的线程(取决于指定的队列类型)。
如果用将任务比作打疫苗的话,那么同步执行就是只有一个护士在打疫苗,所有人必须排队在这个护士这里一个接一个打,但是异步执行是多个护士在打疫苗,大家可以在不同的护士那里排队打疫苗。
队列就是执行任务的队伍,是一种特殊的线性表,采用 FIFO(先进先出),分为『串行队列』和『并发队列』。
- 串行队列:每次执行一个任务,并且任务一个接一个执行(只开启一个线程);
- 并发队列:多个任务可同时执行(可以开启多个线程同时执行任务)。
注意:并发队列只有在使用异步时才有效。
如果将队列比作打疫苗的话,那么就可以看作打疫苗时大家排的队伍。串行队列就是所有人只排了一条长长的队伍一个个打疫苗,而并发队列就是大家排了好几条队伍同时依次打疫苗,但是只有在打疫苗的护士也有好几个(异步)时才有效。
主队列
这里我们需要认识一下主队列:
- 主队列是一个特殊的串行队列,可使用
dispatch_get_main_queue()
方法获得主队列; - 代码默认都是放到主队列里的,主队列中的代码都会在主线程中运行;
- 在主队列中使用同步,会导致线程卡死。
任务和队列的不同组合
串行队列 | 并发队列 | 主队列 | |
---|---|---|---|
同步 | 没有开启新线程,串行执行任务 | 没有开启新线程,串行执行任务 | 线程卡死,App崩溃 |
异步 | 开启了一条新线程,并在其中串行执行任务 | 开启了新线程,并发执行任务 | 没有开启新线程,在主线程中串行执行任务 |
下面还是用图来形象的说明一下这六种组合产生的不同结果:
串行队列+同步
串行队列就是一支普通的队伍,队伍里的人都在排队干一件事,这件事可以是打疫苗也可以是打饭,而打疫苗(新添加的同步任务)打完以后就去旁边蹲着观察30分钟了,下面一个人接着打饭,互相不影响,一个接一个的依次进行。
并发队列+同步
此时并发队列并没有排成队伍,所有人都前往一处(主线程)办事,谁先到谁就先办,然后下一个人等上一个人办完再办,按先来后到的顺序(代码的顺序)。
主队列+同步
主队列就是一支特殊的队伍,队伍里的人都在排队干一件事,这件事同样可以是打疫苗也可以是打饭,但跟普通串行不同的是,下一个人需要等到上一个人做完事并且反馈了结果之后才能干自己的事,而打疫苗(新添加的同步任务)打完以后必须观察30分钟确认没不良反应后,下面一个人才能接着打饭,此时就造成了主队列和添加的同步互相等待,主线程卡死。
串行队列+异步
串行就是排了一支普通的队伍,但队伍去了另外一处依次排队干事了(新开启的异步线程)。
并发队列+异步
此时的并发队列,有几支队伍,就会相应的排成几条队(新建几条新线程),这也是经典的异步方法。
主队队列+异步
主队列作为一支特殊的队伍(轴得很),在被告知去另外一处排队时,毅然决然的拒绝了,并表示我就要在你这(主线程)排队依次干事。
以上就是关于GCD队列和任务各种组合,直观的比喻解释了,关于GCD的具体讲解,文首处本文的参考文章讲解得非常好,大家可以参考之。