美文网首页Effective Objective-C 2.0
📚Effective OC - Tip41 多用派发队列,少用同

📚Effective OC - Tip41 多用派发队列,少用同

作者: 小万叔叔 | 来源:发表于2017-01-11 13:25 被阅读10次

    少用@synchronized self 方法

    //case 1 : @synchoronized self
    //这样做,只要访问self,就会被锁,抢夺同一个锁,效率级低,还不如直接atomic 属性呢
    - (void)setLockerStr:(NSString *)lockerStr {
        @synchronized (self) {
            _lockerStr = lockerStr;
        }
    }
    - (NSString *)lockerStr {
        __block NSString* blockStr;
        @synchronized (self) {
            blockStr = _lockerStr;
        }
        return blockStr;
    }
    
    //NSLock
    - (void)setLockerStr:(NSString *)lockerStr {
        [_lock lock];
        _lockerStr = lockerStr;
        [_lock unlock];
    }
    
    - (NSString *)lockerStr {
        NSString* localStr;
        [_lock lock];
        localStr =  _lockerStr;
        [_lock unlock];
        return localStr;
    }
    

    使用串行同步方法,而不是主动调用锁

    //但是使用同步块,会调用拷贝block,在性能上也许不如直接锁
    _syncQueue = dispatch_queue_create("syncQueue", nil);
    - (void)setLockerStr:(NSString *)lockerStr {
        dispatch_sync(_syncQueue, ^{
            _lockerStr = lockerStr;
        });
    }
    - (NSString *)lockerStr {
        __block NSString* blockStr;
        dispatch_sync(_syncQueue, ^{
            blockStr = _lockerStr;
        });
        return blockStr;
    }
    

    如果改为并行呢,读可以多并行,而只有写是阻塞的呢

    /**
        dispatch_barrier_sync
      dispatch_barrier_async
        栅栏 block 必须单独执行,不能与其他块并行,只对并行队列有意义,因为串行队列的块总是按顺序来逐个执行的
      这里再次说明下, sync 和 async 是决定是否阻塞当前线程,而决定执行是否并行,是由所放的队列来决定的
      写方法表示,可以放到并行操作里面去写,但是由于 barrier 的特性,当前的 block 一定会再前面操作之后执行,像
    一道栅栏一样横在哪里, 而读操作,由于要得到接口,所以是阻塞当前线程的,但是实际多线程里面却是并行操作的。
     
         并发队列
     | Read Read
     | Read Read Read
     | Write(barrier)
     | Read Read
     |
     ⤵️
    时序
    */
    - (void)setLockerStr:(NSString *)lockerStr {
        dispatch_barrier_async(_asyncQueue, ^{
            _lockerStr = lockerStr;
        });
    }
    - (NSString *)lockerStr {
        __block NSString* blockStr;
        dispatch_barrier_sync(_asyncQueue, ^{
            blockStr = _lockerStr;
        });
        return blockStr;
    }
    

    相关文章

      网友评论

        本文标题:📚Effective OC - Tip41 多用派发队列,少用同

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