GCD-Barrier

[TOC]
Barrier: n. (用来禁止通行的各种)障碍物(如: 栅栏和关卡)

在看GCD的barrier如何使用前,我们先了解barrier的英文意思.
barrier的用法非常简单,这里我就不过多赘述,且看下面的代码:

- (void)barrier
{
    dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.for", DISPATCH_QUEUE_CONCURRENT);
    NSMutableArray *arr = @[].mutableCopy;
    [arr addObject:@(1)];
    dispatch_async(queue, ^{
        NSLog(@"bl1 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        NSLog(@"bl2 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        [arr addObject:@(0)];
        [NSThread sleepForTimeInterval:2.0];
        [arr addObject:@(7)];
        NSLog(@"finished: %@", arr);
    });
    dispatch_async(queue, ^{
        NSLog(@"bl4 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        NSLog(@"bl5 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2.5];
        NSLog(@"bl6 arr: %@", arr);
    });
}

/*
输出:
2016-12-29 17:53:10.681 GCD-Barrier[33828:1500632] bl2 arr: (
    1
)
2016-12-29 17:53:10.681 GCD-Barrier[33828:1500627] bl1 arr: (
    1
)
2016-12-29 17:53:10.681 GCD-Barrier[33828:1500646] bl4 arr: (
    1,
    0
)
2016-12-29 17:53:10.681 GCD-Barrier[33828:1500632] bl5 arr: (
    1,
    0
)
2016-12-29 17:53:12.754 GCD-Barrier[33828:1500647] finished: (
    1,
    0,
    7
)
2016-12-29 17:53:13.229 GCD-Barrier[33828:1500654] bl6 arr: (
    1,
    0,
    7
)
*/

上面这段代码模拟了一个异步读写操作. bl1bl2读取到的结果都是1,而bl4bl5读取到的结果是1,0,我在bl2bl4之间插入了一个写入操作,第一个是一个没有延迟的写入操作,然后模拟了延迟2.5秒的一个写入操作,插入了一个7,结果是只有加了延迟的bl6的读取操作是正确的.
为什么这样说,因为在同一时间,不同的用户进行了不同的操作,比如评论,当我看别人的评论的时候,恰巧有个人刚提交了一个评论,提交评论时,需要执行一个插入操作,但是这时我读取到的评论列表没有那个人刚刚提交的评论,这样有可能会造成某种误会.
所以我们需要用些手段,当有写入操作的时候,不能让别的线程来进行读取,等写入完毕后,再允许别的线程读取.
GCD很方便的为我们提供了这种功能,且看下面这段代码:

- (void)barrier
{
    dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.for", DISPATCH_QUEUE_CONCURRENT);
    NSMutableArray *arr = @[].mutableCopy;
    [arr addObject:@(1)];
    dispatch_async(queue, ^{
        NSLog(@"bl1 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        NSLog(@"bl2 arr: %@", arr);
    });

    dispatch_barrier_async(queue, ^{
        [arr addObject:@(0)];
        [NSThread sleepForTimeInterval:2.0];
        [arr addObject:@(7)];
        NSLog(@"finished: %@", arr);
    });

    dispatch_async(queue, ^{
        NSLog(@"bl4 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        NSLog(@"bl5 arr: %@", arr);
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2.5];
        NSLog(@"bl6 arr: %@", arr);
    });
}
/**
输出结果:
2016-12-30 09:40:01.353 GCD-Barrier[35219:1890287] bl1 arr: (
    1
)
2016-12-30 09:40:01.353 GCD-Barrier[35219:1890761] bl2 arr: (
    1
)
2016-12-30 09:40:03.385 GCD-Barrier[35219:1890761] finished: (
    1,
    0,
    7
)
2016-12-30 09:40:03.385 GCD-Barrier[35219:1890287] bl5 arr: (
    1,
    0,
    7
)
2016-12-30 09:40:03.385 GCD-Barrier[35219:1890761] bl4 arr: (
    1,
    0,
    7
)
2016-12-30 09:40:05.924 GCD-Barrier[35219:1890762] bl6 arr: (
    1,
    0,
    7
)
*/

上面的代码,我们使用了dispatch_barrier_async这个方法,这个方法里面的任务执行的时候,会挂起当前队列里其他的任务,当这个方法里的任务执行完成之后,别的任务再继续执行.如下图:
dispatch_barrier_async
嗯..就酱.
联系方式: 958246321

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值