一、GCD的概念:
GCD(Grand Central Dispatch),是有Apple公司开发的一个多核编程的解决方案,用以优化应用程序支持多核处理器,是基于线程模式之上执行并发任务。
二、GCD的优点:
1.利用设备多核进行并行运算
2.GCD自动充分使用设备的CPU内核
3.GCD自动管理线程的生命周期(线程创建、线程调度、线程销毁)
4.使用简单
三、GCD中的任务和队列
1.任务就是需要GCD处理的操作,即需要多线程处理的代码。
1.1任务的执行分两种:同步执行、异步执行
同步执行:
只能在当前线程中执行,不具备开启新线程能力,顺序等待、有序执行
异步执行:
具备开启新线程能力,并发执行,不需要等待任务执行结束才能继续其他操作
2.队列就是存放被执行任务的等待队列,是一种特殊的线形表,采用先进先出的原则
2.1队列分两类:串行队列、并发队列,两者主要区别是执行顺序不同及是否有开启新线程能力
2.1.1 串行队列:
每次只会调度一个任务,知道上个任务处理完成才会开始调度处理下一个任 务
2.1.2并发队列:
同时调度分发多个任务出去同时执行
3.GCD使用步骤:
3.1.创建一个任务队列(串行队列、并发队列)
3.2.将任务添加到创建的等待队列并指定任务的执行类型(异步、同步)
4.队列的创建、获取方法:
4.1.使用dispatch_queue_create创建队列,需要传入两个参数:
4.1.1.第一个参数表示队列的唯一标识符,用于 DEBUG,可为空。队列的名称推荐使用应用程序 ID 这种逆序全程域名
4.1.2.第二个参数用来设置为串行队列还是并发队列, DISPATCH_QUEUE_SERIAL表示串行队列,DISPATCH_QUEUE_CONCURRENT表示并发队列
4.1.3.示例如下:
// 串行队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
// 并发队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
4.2.创建串行队列,GCD默认提供了:主队列(Main Dispatch Queue)
4.2.1.所有主队列的任务会安排至主线程执行
4.2.2.主队列获取方法:dispatch_get_main_queue
4.3.创建并发队列,GCD默认提供了:全局并发队列(Global Dispatch Queue)
4.3.1.可以使用 dispatch_get_global_queue 方法来获取全局并发队列。需要传入两个参数:1.队列优先级级别(默认:DISPATCH_QUEUE_PRIORITY_DEFAULT)2.队列标识(默认:0)
4.3.2:
// 全局并发队列的获取方法
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
4.4任务创建方法:
GCD提供了同步执行任务创建方法:dispatch_sync和异步执行任务创建方法:dispatch_async
例:
// 同步执行任务创建方法
dispatch_sync(queue, ^{
// 这里放同步执行任务代码
});
// 异步执行任务创建方法
dispatch_async(queue, ^{
// 这里放异步执行任务代码
});
4.5. 任务和队列不同组合方式的区别
我们先来考虑最基本的使用,也就是当前线程为 『主线程』 的环境下,『不同队列』+『不同任务』 简单组合使用的不同区别。暂时不考虑 『队列中嵌套队列』 的这种复杂情况。
『主线程』中,『不同队列』+『不同任务』简单组合的区别:
区别 并发队列 串行队列 主队列
同步(sync) 不开启新线程 不开启新线程 死锁
串行执行 串行执行
异步(async) 开启新线程 开启1条新线程 不开启新线程
并发执行 串行执行 串行执行
注意:从上边可看出: 『主线程』 中调用 『主队列』+『同步执行』 会导致死锁问题。
这是因为 主队列中追加的同步任务 和 主线程本身的任务 两者之间相互等待,阻塞了 『主队列』,最终造成了主队列所在的线程(主线程)死锁问题。
而如果我们在 『其他线程』 调用 『主队列』+『同步执行』,则不会阻塞 『主队列』,自然也不会造成死锁问题。最终的结果是:不会开启新线程,串行执行任务。