美文网首页
block与GCD--41:多用派发队列,少用同步锁

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

作者: 皆为序幕_ | 来源:发表于2018-08-02 17:30 被阅读0次

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

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

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

    使用串行同步队列

    • 将读取/写入都安排在同一个队列里,即可保证数据同步
    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;  
        });  
    }  
    
    • 多个获取方法可以并发执行,而获取方法与设置方法之间不能并发执行,利用这个特点,可以优化代码。改为并发队列
    _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;
            });
    }
    

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

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

    相关文章

      网友评论

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

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