GCD-栅栏函数 dispatch_barrier_async
2015-08-28 本文已影响0人
笨笨编程
-
dispatch_group
和dispatch_barrier
的区别?
案例1:如果有A、B、C 三个任务,需要三个任务(可能耗时)执行结束后再执行任务D,怎么实现?
- 第一种方案使用
dispatch_group
注意:dispatch_group_enter
和dispatch_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_group
和 dispatch_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任务
- 我们再聊聊栅栏函数
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 ----------");
打印出的结果:确实分割了前后执行的任务
栅栏函数(同步)