前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >block与GCD--41:多用派发队列,少用同步锁

block与GCD--41:多用派发队列,少用同步锁

作者头像
xy_ss
发布2023-11-22 08:30:30
1280
发布2023-11-22 08:30:30
举报
文章被收录于专栏:浮躁的喧嚣

使用多线程的时候可能会访问同一块资源,这样就很容易引发数据错乱和数据安全等问题,这时候就需要我们保证每次只有一个线程访问这一块资源,锁应运而生。

  • @synchronization
代码语言:javascript
复制
- (void)synchronizedMethod{
    @synchronized(self)
    {
        // 关键代码;
    }
}
  • @NSLock
代码语言:javascript
复制
_ lock = [[NSLock alloc]init];
- (void)synchronizedMethod{
     [_ lock lock];
        // 关键代码;
     [_ lock unlock];
}

这两种都会遇到死锁现象。而且其效率并不高。

使用串行同步队列

  • 将读取/写入都安排在同一个队列里,即可保证数据同步
代码语言:javascript
复制
dispatch_queue_t _syncQueue = dispatch_queue_create("com.effective-c.syncQueue", NULL);  

-(NSString*) someString {  
    __block NSString* localSomething;  
    dispatch_sync(_syncQueue,^{  
        localSomeString = _someString;  
    });  
    return localSomeString  
}  
-(void) setSomeString:(NSString*) someString{  
    dispatch_sync(_syncQueue,^{  
        _someString = someString;  
    });  
}  
  • 多个获取方法可以并发执行,而获取方法与设置方法之间不能并发执行,利用这个特点,可以优化代码。改为并发队列
代码语言:javascript
复制
_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;
        });
}

栏栅块必须单独执行,不能与其他块并行,这只对并发队列有意义,因为串行队列中的块总是按顺序逐个来执行的。并发队列如果发现接下来要处理的块是个栏栅块,那么就一直等到当前所有并发块都执行完毕,才会单独执行这个栏栅块。待栏栅块执行过后,再按正常方式继续向下处理。

设置方法中使用了栏栅块之后,对属性的读取操作依然可以并发执行,但是写入操作却必须单独执行了

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用串行同步队列
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档