美文网首页iOS Developer
GCD 并行队列使用

GCD 并行队列使用

作者: 一一闪闪亮京京 | 来源:发表于2017-02-10 16:34 被阅读0次

通常情况下,我们在处理网络请求和处理大数据时,会使用多线程技术,在新线程中进行操作,防止主线程卡顿,降低用户体验.

1.基本操作
步骤:新建线程,处理数据,返回主线程刷新UI

//0.开启新线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//1.此处处理数据
//doSomething

//2.返回主线程
dispatch_sync(dispatch_get_main_queue(), ^{
//3.刷新UI

});

});

2.某个操作依赖其他操作,需要等待其他几个操作完成再去执行。
A.使用GCD的group
步骤:新建队列和group,添加多个操作,注册group完成通知。

//“全部完成”操作 依赖 “1”,“2”,“3”三个操作
    NSLog(@"主线程");
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, globalQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"----- 1 -----");
    });
    dispatch_group_async(group, globalQueue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"----- 2 -----");
    });
    dispatch_group_async(group, globalQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"----- 3 -----");
    });
    dispatch_group_notify(group, globalQueue, ^{
        NSLog(@"全部完成");
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"主线程");
        });
    });
1.png

从控制台信息可以看到。“全部完成”是在三个线程执行完成后调用的。从线程ID看到,打印“全部完成”的线程是三个线程中最后结束的那个线程。

B.使用栅栏隔离
步骤:新建并行队列,添加优先执行的操作,添加栅栏,添加后执行的操作

    dispatch_queue_t current1 = dispatch_queue_create("myQueue1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"1");
        }
    });
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"2");
        }
    });
    dispatch_barrier_async(current1, ^{
        NSLog(@"隔离作用");
    });
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"3");
        }
    });
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"4");
        }
    });
2.png

执行完1.2两个操作,然后才执行3.4操作。并且从线程ID看,“隔离操作”使用了“2”的线程,“隔离操作”完成后,“3”又使用了这个线程,系统并未给“3”“4”新建线程,而是使用了旧线程,节约了系统开销。

要知道实际此处有apple提供了两个方法,dispatch_barrier_async 和 dispatch_barrier_sync,两者区别在哪呢?
下面从代码上探究一下
a.在上述代码基础上增加两行log

    NSLog(@"主线程");
    dispatch_queue_t current1 = dispatch_queue_create("myQueue1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"1");
        }
    });
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"2");
        }
    });
    dispatch_barrier_async(current1, ^{
        NSLog(@"隔离作用");
    });
    NSLog(@"aa");
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"3");
        }
    });
    NSLog(@"bb");
    dispatch_async(current1, ^{
        for (NSInteger i = 0 ; i < 2; i++) {
            NSLog(@"4");
        }
    });

运行结果:

3.png

“aa”和“bb”在隔离前输出。

B.将dispatch_barrier_async 改为 dispatch_barrier_sync
运行结果:

4.png

“aa”和“bb”在隔离后输出。

两者对比发现,控制台输出“aa”,"bb"时间是不同的,一个在隔离前,一个在隔离后,说明在将任务插入到queue的时候,dispatch_barrier_sync需要等待自己的任务(“隔离作用”)结束之后才会插入被写在它后面的任务(3、4);而dispatch_barrier_async将自己的任务(“隔离作用”)插入到queue之后,不会等待自己的任务结束,它会继续把后面的任务(3、4)插入到queue

所以,dispatch_barrier_async的不等待(异步)特性体现在将任务插入队列的过程,它的等待特性体现在任务真正执行的过程。

相关文章

  • 多线程【转】

    文章目录GCD简介任务和队列GCD的使用步骤队列的创建方法任务的创建方法GCD的基本使用并行队列 + 同步执行并行...

  • iOS多线程--GCD篇

    GCD 文章目录GCD简介任务和队列GCD的使用步骤队列的创建方法任务的创建方法GCD的基本使用并行队列 + 同步...

  • iOS多线程--彻底学会多线程之『GCD』

    GCD 文章目录 GCD简介 任务和队列 GCD的使用步骤 队列的创建方法 任务的创建方法 GCD的基本使用 并行...

  • 关于多线程GCD 串行/并行、同步/异步

    一、GCD串行/并行队列创建 串行队列: 并行队列: 二、GCD串行/并行队列同步/异步执行 执行内容1: 执行结...

  • AFNetworking 中 GCD 的使用(5)

    GCD in AFNetworking 的使用 AFImageDownloader 图片下载 创建队列,串行,并行...

  • GCD 并行队列使用

    通常情况下,我们在处理网络请求和处理大数据时,会使用多线程技术,在新线程中进行操作,防止主线程卡顿,降低用户体验....

  • GCD多线程问题整理

    1.GCD队列有哪几种类型?有哪几种队列? GCD队列分为串行队列、并行队列两种类型;队列有主串行队列、全局并行队...

  • GCD的学习笔记(One)

    并行和并发 GCD简介 GCD的任务 GCD的队列 GCD创建队列或获取队列的方法 任务的执行方式:同步执行(同步...

  • GCD 细细的读

    目录 前言 为什么选择GCD? 串行队列、并行队列、同步、异步 线程死锁解析 DispatchQueue的使用 D...

  • GCD死锁

    GCD死锁原因 GCD死锁的原因是队列阻塞,而不是线程阻塞! 串行和并行 串行和并行都是相对于队列而言的-队列(负...

网友评论

    本文标题:GCD 并行队列使用

    本文链接:https://www.haomeiwen.com/subject/gcigittx.html