GCD-栅栏函数 dispatch_barrier_async

2015-08-28  本文已影响0人  笨笨编程
  1. dispatch_groupdispatch_barrier 的区别?
    案例1:如果有A、B、C 三个任务,需要三个任务(可能耗时)执行结束后再执行任务D,怎么实现?
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
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 ----------");

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


栅栏函数(同步)
上一篇下一篇

猜你喜欢

热点阅读