美文网首页
dispatch_barrier_sync和dispatch_b

dispatch_barrier_sync和dispatch_b

作者: 御雪飞斐 | 来源:发表于2019-03-26 12:59 被阅读0次

多个线程执行同一份代码时,很可能会造成数据不同步。使用GCD来为代码加锁的方式解决这个问题。
方案一:使用串行同步队列来将读写操作都安排到同一个队列里

_syncQueue = dispatch_queue_create("com.effectiveobjectivec.syncQueue", NULL);

//读取字符串
- (NSString*)someString {

         __block NSString *localSomeString;
         dispatch_sync(_syncQueue, ^{
            localSomeString = _someString;
        });
         return localSomeString;

}

//设置字符串
- (void)setSomeString:(NSString*)someString {

     dispatch_sync(_syncQueue, ^{
        _someString = someString;
    });
}

方案二:将写操作放入栅栏快中,让他们单独执行;将读取操作并发执行

_syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//读取字符串
- (NSString*)someString {

     __block NSString *localSomeString;
     dispatch_sync(_syncQueue, ^{
        localSomeString = _someString;
    });
     return localSomeString;
}

//设置字符串
- (void)setSomeString:(NSString*)someString {

     dispatch_barrier_async(_syncQueue, ^{
        _someString = someString;
    });

}
显然,数据的正确性主要取决于写入操作,那么只要保证写入时,线程是安全的,那么即便读取操作是并发的,也可以保证数据是同步的。
这里的dispatch_barrier_async方法使得操作放在了同步队列里“有序进行”,保证了写入操作的任务是在串行队列里。

正文:
前提:现在要插入一个任务0,这个任务0要在1、2、3都并发执行完了之后才能执行,而4、5、6号任务要在这个任务0结束后才允许并发。

dispatch_barrier_sync和dispatch_barrier_async的共同点: 
1、都会等待在它前面插入队列的任务(1、2、3)先执行完 
2、都会等待他们自己的任务(0)执行完再执行后面的任务(4、5、6)

dispatch_barrier_sync和dispatch_barrier_async的不共同点: 
在将任务插入到queue的时候,dispatch_barrier_sync需要等待自己的任务(0)结束之后才会继续程序,然后插入被写在它后面的任务(4、5、6),然后执行后面的任务 
而dispatch_barrier_async将自己的任务(0)插入到queue之后,不会等待自己的任务结束,它会继续把后面的任务(4、5、6)插入到queue

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

个人理解:

asyn不阻塞当前线程,barrier只是阻塞同队列中后面的操作。
syn阻塞当前线程,barrier同时阻塞同队列中后面的操作。

相关文章

网友评论

      本文标题:dispatch_barrier_sync和dispatch_b

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