如何实现同步机制?

实现同步机制目前知道有3中方法,分别是@synchronized、NSLock、GCD。

@synchronized

@synchronized:它会根据指定的对象,自动创建一个锁,并等待块中的代码执行完毕,锁就释放了。

- (NSString *)someString {
   @synchronized(self) {
      return _someString;
  }
}

- (void)setSomeString:(NSString *)someString {
    @synchronized(self) {
        _someString = someString;
    }
}

缺点:滥用@synchronized会危险,因为所有同步块都会彼此抢夺一个锁,要是很多个属性能这么写的话,那么每个属性的同步块都要等其他所有同步块执行完毕才能执行,这会大大降低代码的执行效率。

NSLock

_lock = [[NSLock alloc] init];

- (void)sychronizedMethod {
    [_lock lock];
    //Safe
    [_lock unlock];
}

缺点:极端情况下,同步块会导致死锁。而且NSLock效率也不是很高。

GCD

它能以更简单,更高效的形式为代码加锁。

1.使用串行同步队列来代替同步块或锁对象

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

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

- (void)setSomeString:(NSString *)someString {
    dispatch_sync(_syncQueue, ^{
        _someString = someString;
})
}

我们都知道,串行同步队列即任务按顺序执行,并且不回开辟新的线程,使读取操作与写入操作都安排在同一个队列里,即可保证数据同步。

2.使用串行异步队列来代替同步块或锁对象

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

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

- (void)setSomeString:(NSString *)someString {
    dispatch_async(_syncQueue, ^{
        _someString = someString;
})
}

这是把设置方法改成了异步。因为是串行队列,读取操作与写入操作依然会按顺序执行。

3.并发队列+dispatch_barrier_async

_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能够使之前加入并发队列的块先执行完,再单独执行栅栏块,待栅栏块执行过后,再按正常方式向下处理。

本例中,使用栅栏块来实现属性的设置方法,来保证读取操作可以并发执行,但是写入操作是单独执行的。

你可能感兴趣的:(如何实现同步机制?)