iOS多线程管理(一)

1.概念理解:

队列(Queue)队列是一种先进先出(FirstInFirstOut,FIFO)的线性表。它只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素称为入队,从队列中删除元素称为出队。

**iOS中有两种队列:
****串行队列:按照指派的顺序来执行任务,前一个执行完下一个才能执行。
****并行队列:能够同时执行一个或多个任务,执行任务的顺序并不一定。
**其中主队列是串行队列,全局队列是并行队列。

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码。在 GCD 中是放在 block 中的。执行任务有两种方式:『同步执行』 和 『异步执行』。两者的主要区别是:是否等待队列的任务执行结束,以及是否具备开启新线程的能力。

2.代码验证

同步执行 + 串行队列:不开辟新的子线程,任务在按添加进队列顺序依次在当前线程中执行。

总结:同步执行+串行队列不开辟新的线程,任务是按添加的循序依次在当前的中执行,这里应该注意的是在当前的线程中。如果当前在主线程,那么任务就在主线程执行,如果syncWithSerialQueue方法放在了子线程,那么就在子线程执行。

异步执行 + 串行队列: 开辟了新的子线程,任务在子线程中按顺序执行。

总结:异步执行+串行队列,开辟了一条子线程,任务按添加的顺序依次执行。同样在串行队列中,结合前面一个同步执行任务来看,通过sync添加的任务,是立刻会被执行;而通过async添加的任务,是在当前线程正在执行的任务执结束之后,再按添加的顺序依次执行的。

同步执行 + 并发队列: 没有开启子线程,任务在按添加进队列顺序依次执行。

总结:同步执行 + 并发队列: 没有开启子线程,任务在按添加进队列顺序依次执行。虽然是并发的队列,但是同步执行的情况下,第二个任务需要等待第一个任务的完成,所以没有必要开辟多个线程,任务在同一个线程中,依次执行。

异步执行 + 并发队列:开辟了多个子线程,任务执行是异步执行,顺序不固定。

总结:异步执行 + 并发队列:开辟了多个子线程,任务执行是异步执行,顺序错乱且不固定。可以看到GCD对于线程执行任务的调度,在同一个任务里执行的打印都不在一起,这也就是说并发的情况下,CPU是在不停的切换线程执行任务的。

同步执行 + 主队列:如果在主线程中,iOS低版本系统会卡死主线程,高版本系统会直接崩溃,如果不在主线程上执行,则和普通的同步执行 + 主队列一样,不开辟线程,任务按顺序依次执行,因为任务是添加到主队列,所以任务在主线程中执行。                        (卡死和崩溃的区别,记不得是iOS x?的系统啦!!!)

总结:同步执行 + 主队列的情况下,如果在主线程中添加则会卡死崩溃,如果在子线程中添加任务则任务会按照添加顺序在主线程中依次执行。

卡死崩溃原因解析:主队列是一个特殊的串行队列,线程会立刻执行通过dispatch_sync函数添加到队列的任务,所以就打断了主线程的当前任务,然而队列又是先进先出的,此时准备执行的这个任务必须要等待主线程当前的任务结束才能执行,而这个刚添加的任务又需要立刻执行,主线程当初执行的任务在等待dispatch_sync函数添加进来的任务执行结束。所以就造成了相互等待,卡死了主线程。

异步执行 + 主队列:没有开辟新的线程,任务按添加进来的顺序执行。

总结:异步执行 + 主队列 没有开辟新的线程,任务按添加进来的顺序执行, 然后在上面的 异步执行 + 串行队列的时候,是开辟了一个子线程的。所以在异步的情况下,非主队列里的任务会开辟新的线程来执行,主队列的任务会由主线程来优先执行。

同步执行 + 全局队列: 没有开辟新的线程,任务按添加顺序依次执行。

总结:同步执行 + 全局队列: 没有开辟新的线程,任务按添加顺序依次执行。全局队列是一个并发队列。所以 同步执行+全局队列 VS 同步执行+并发队列 是一样的效果。

异步执行 + 全局队列: 开辟了新线程,执行顺序是错乱的。

总结:异步执行 + 全局队列: 开辟了新线程,执行顺序是错乱的。所以 异步执行+全局队列 VS 异步执行+并发队列 是一样的效果。

结语:
1,是否开启新的线程取决于是否是异步执行,异步执行才拥有开辟开启新的线程能力。
2,同步执行不开启新的线程,任务依赖前一个任务的完成,没有必要开启新的线程。
3,异步 + 主线程的话,并不开启新的线程!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享