GCD 中同步、异步、串行、并行

串行队列 VS 并行队列

GCD 中的队列是用来放置需要执行的任务的,任务的取出遵循队列的先进先出的原则。
GCD 将队列中的任务取出,并放置到对应的线程中执行。

串行队列:同一时刻只有一个任务在执行,后面的任务需要等待正在执行的任务结束,才能执行。
并行队列:同一时刻可以有多个任务在执行,后面的任务不需等待,只要有可以执行任务的线程,就可以执行。其中,执行任务的线程数量取决于当前系统的状态,包括处理数、CPU核数、CPU负荷等系统状态。

同步派发 VS 异步派发

派发指的是将任务追加到指定的队列中,等待 GCD 取出执行。
同步派发 dispatch_sync:一个任务的追加会等待当前任务执行完,再进行。同步,保证了任务执行的顺序。
异步派发 dispatch_async:一个任务的追加不等待当前任务执行完,直接追加在队列中。因为任务的追加不等待,直接追加,也就需要 GCD 为其开启新线程来执行操作。

下面将分为四步分别测试:

  • 同步派发串行队列
  • 异步派发串行队列
  • 同步派发并步队列
  • 异步派发并行队列

同步派发串行队列

//同步派发串行队列
- (void)syncSERIAL
{
    dispatch_queue_t serQueue = dispatch_queue_create("zn.serQueue", DISPATCH_QUEUE_SERIAL);
    for (int i=0; i<10; i++) {
        dispatch_sync(serQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

异步派发串行队列

//异步派发串行队列
- (void)asyncSERIAL
{
    dispatch_queue_t serQueue = dispatch_queue_create("zn.serQueue", DISPATCH_QUEUE_SERIAL);
    for (int i=0; i<10; i++) {
        dispatch_async(serQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

同步派发并行队列

//同步派发并行队列
- (void)syncConcurrent
{
    dispatch_queue_t conQueue = dispatch_queue_create("zn.conQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i=0; i<10; i++) {
        dispatch_sync(conQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

异步派发并行队列

//异步派发并行队列
- (void)asyncConcurrent
{
    dispatch_queue_t conQueue = dispatch_queue_create("zn.conQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i=0; i<10; i++) {
        dispatch_async(conQueue, ^{
            NSLog(@"时间在:%@进行第:%d个输出  %@ \n",[[NSDate date] description],i,[NSThread currentThread]);
            sleep(1);
        });
    }
}
image.png

注意:此时的输出偶尔可能是有序的,但多测试几次就会发现,此时是异步执行,同时执行,输出顺序是无需的。

总结:

同步派发,因为要等待当前任务的进行,所以不需要开启新线程;
异步派发,因为不需等待当前任务,可以开启新线程执行任务。

串行队列,任务一个一个进行,在一条线程中即可完成;
并行队列,可同时进行多个任务,会在多条线程中进行。

注意:有兴趣的同学可以试试把上面的4个代码混合调用(同步串行、同步并行、异步串行、异步并行交叉使用)或许会发现新大陆哟!在这先不做赘述

下面的这句话可能更容易理解:

dispatch_ async将block追加在队列中,不做等待立即执行block中的操作--异步    
串行队列:按序执行
并行队列:立即执行

dispatch_ sync将block追加在队列中,按顺序执行,后面的操作需要等待前面的操作执行完--同步
串行队列:按序执行
并行队列:按序执行

本文部分内容转载自:https://yiweifen.com/html/news/WaiYu/101972.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。通过本文,您将了解到: 1. GCD 简介 2. G...
    晓_我想去环游世界阅读 4,852评论 2 8
  • 从哪说起呢? 单纯讲多线程编程真的不知道从哪下嘴。。 不如我直接引用一个最简单的问题,以这个作为切入点好了 在ma...
    Mr_Baymax阅读 7,814评论 1 17
  • 本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。这大概是史上最详细、清晰的关于 GCD 的详细讲...
    花花世界的孤独行者阅读 3,502评论 0 1
  • 场景一: 医院儿科病房,护士拿着一堆空管来到病床前:“小朋友,准备抽血了。” 我看着这么多空管数了数,15管。不禁...
    愚箏阅读 2,372评论 0 1
  • 借我一棵开花的树, 菩提下,那时你最美的时刻。 借我一把穿行于雨巷的油纸伞, 偶遇一朵丁香。 借我三百公里的铁轨,...
    老王和老吴阅读 1,598评论 1 2

友情链接更多精彩内容