但往往形成了这种固有的套路以后,自己代码写着写着的时候回头看就很容易产生疑问,为什么要这样写?到底什么是队列?什么是任务?
任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码。而GCD中的任务只是一个代码块,它可以指一个block或者函数指针。执行任务有两种方式:同步执行(sync)和异步执行(async)。两者的主要区别是:是否等待队列的任务执行结束,以及是否具备开启新线程的能力。
同步执行(sync):
同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。
只能在当前线程中执行任务,不具备开启新线程的能力。
异步执行(async):
异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务。
可以在新的线程中执行任务,具备开启新线程的能力。
队列(Dispatch Queue):这里的队列指执行任务的等待队列,即用来存放任务的队列。队列是一种特殊的线性表,采用 FIFO(先进先出)的原则,即新任务总是被插入到队列的末尾,而读取任务的时候总是从队列的头部开始读取。每读取一个任务,则从队列中释放一个任务。在 GCD 中有两种队列:串行队列和并发队列。两者都符合 FIFO(先进先出)的原则。两者的主要区别是:执行顺序不同,以及开启线程数不同。
串行队列(Serial Dispatch Queue):
每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)
并发队列(Concurrent Dispatch Queue):
可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)
这以上对任务和队列的理解是源自这两篇很好的文章:
巧谈GCD
iOS多线程:『GCD』详尽总结
有了上面大神们对队列和任务的解释,现在对GCD也有了些许概念。在这个基础上,我来说说我的一个技巧理解GCD的方式。首先我们可以把任务看做是水滴,而队列就是管道了。串行队列的管道很细,只有容纳下一滴水的直径。而并发队列的管道的直径很粗,可以容纳下很多水滴。下面就具体到队列与任务之间的搭配了。
同步+串行
不会开启新线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务。任务1,任务2依次执行
同步+串行
同步+并发
在当前线程中执行任务,不会开启新线程,执行完一个任务,再执行下一个任务。因为是同步的任务,所以会等待任务1执行完,在执行任务2。同理,任务3也是等任务2执行完毕之后再开始执行
同步+并发
同步任务是没有开辟线程的能力的
异步+串行
会开启新线程,但是因为任务是串行的,执行完一个任务,再执行下一个任务
异步+串行
异步+并发
可以开启多个线程,任务交替(同时)执行。会并行执行多个任务,这也是我们最常用的一种方式。
异步+并发
异步任务是有开辟线程的能力的,但是在主队列中,异步就失去了这种能力
同步+主队列
在不同线程中调用结果也是不一样,在主线程中调用会出现死锁,而在其他线程中则不会。
异步+主队列
只在主线程中执行任务,执行完一个任务,再执行下一个任务。
队列和任务组合的总结 |