美文网首页
GCD-栅栏函数 dispatch_barrier_async

GCD-栅栏函数 dispatch_barrier_async

作者: 笨笨编程 | 来源:发表于2015-08-28 09:55 被阅读0次
    1. dispatch_groupdispatch_barrier 的区别?
      案例1:如果有A、B、C 三个任务,需要三个任务(可能耗时)执行结束后再执行任务D,怎么实现?
    • 第一种方案使用 dispatch_group 注意:dispatch_group_enterdispatch_group_leave 是成对出现
    NSLog(@"dispatch_group");
    
    dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"开始任务A");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"结束任务A");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"开始任务B");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"结束任务B");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"开始任务C");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"结束任务C");
        dispatch_group_leave(group);
    });
    
    // 当所有任务执行结束后才执行以下代码
    dispatch_group_notify(group, queue, ^{
        NSLog(@"----------> group <----------");
        NSLog(@"开始任务D");
    });
    

    我们看下打印结果:


    dispatch_group.png
    • 第二种方案:使用 dispatch_barrier_async
    NSLog(@"dispatch_barrier");
    
    dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务A,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:3];
        NSLog(@"结束任务A");
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务B");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"结束任务B");
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务C");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"结束任务C");
    });
    // 栅栏函数
    dispatch_barrier_async(queue, ^{
        NSLog(@"----------> barrier <----------");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务D");
    });
    

    我们再看下打印结果:


    dispatch_barrier.png

    我们发现 dispatch_barrier_async 阻塞了下面的代码,必须等到上面代码(耗时)执行结束之后才执行下面的代码。然而,如果我们把栅栏函数注释了再看下打印结果:

    删除栅栏函数结果

    但是,我们还是发现 dispatch_groupdispatch_barrier_async 都能实现以上需求,这尼玛没区别啊,不着急,慢慢看下面这个需求。

    案例2:如果有A、B、C 三个任务,需要三个任务分别按照顺序执行结束后再执行任务D,怎么实现呢?

    dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"开始任务A");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"结束任务A");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"开始任务B");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"结束任务B");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"开始任务C");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"结束任务C");
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"----------> A B C 有顺序 <----------");
        NSLog(@"开始任务D");
    });
    

    我们看下打印结果:


    有顺序执行A、B、C任务
    1. 我们再聊聊栅栏函数 dispatch_barrier_async,看看下面这段代码:
    NSLog(@"dispatch_barrier");
    NSLog(@"---------- 1111111111 ----------");
    
    dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务A,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:3];
        NSLog(@"结束任务A,来自线程:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务B,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:2];
        NSLog(@"结束任务B,来自线程:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务C,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1];
        NSLog(@"结束任务C,来自线程:%@",[NSThread currentThread]);
    });
    NSLog(@"---------- 2222222222 ----------");
    // 栅栏函数
    dispatch_barrier_async(queue, ^{
        NSLog(@"----------> barrier <----------");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务D,来自线程:%@",[NSThread currentThread]);
    });
    NSLog(@"---------- 3333333333 ----------");
    

    先看下输出结果:


    栅栏函数(异步)

    我们第一个问题得出结论是:栅栏函数dispatch_barrier_async确实可以阻塞后面的代码,但是这里发现 这个 33333333 还是先被打印了出来,才执行的栅栏函数。也就是说:栅栏函数阻塞的是子线程的代码,主线程的代码并没有阻塞。当然,这也体现出了 async 异步的特点。那我们在看看 sync 有什么不一样的。

    NSLog(@"dispatch_barrier_sync");
    NSLog(@"---------- 1111111111 ----------");
    
    dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务A,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:3];
        NSLog(@"结束任务A,来自线程:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务B,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:2];
        NSLog(@"结束任务B,来自线程:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"开始任务C,来自线程:%@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:1];
        NSLog(@"结束任务C,来自线程:%@",[NSThread currentThread]);
    });
    NSLog(@"---------- 2222222222 ----------");
    // 栅栏函数(同步)
    dispatch_barrier_sync(queue, ^{
        NSLog(@"----------> barrier <----------");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"开始任务D,来自线程:%@",[NSThread currentThread]);
    });
    NSLog(@"---------- 3333333333 ----------");
    

    打印出的结果:确实分割了前后执行的任务


    栅栏函数(同步)

    相关文章

      网友评论

          本文标题:GCD-栅栏函数 dispatch_barrier_async

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