# 41、多用派发队列、少用同步锁

1、同步块：`@synchronized(self)`（多个属性时不宜这么写）

​ 2、使用锁：`NSLock`or`NSRecursiveLock`递归锁（线程能够多次持有该锁，而不会出现死锁`deadlock`现象）

​ 3、GCD：串行同步队列

```objectivec
_syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- (NSString *)name {
  __block NSString *localName;
  dispatch_sync(_syncQueue, ^{
    localName = _name;
  });
  return localName;
}
- (void)setName:(NSString *)name {
  dispatch_barrier_sync(_syncQueue, ^{ // sync 比 async 效率高一些
    _name = name;
  });
}​ 
```

![读写🔒](https://1957578480-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQPrkdKRBulXdSdQ_wl%2F-MQPrtQBprnU7IBzECBa%2F-MQPsJ-CoHkmZGopMZtg%2F%E8%AF%BB%E5%86%99%E9%94%81.png?alt=media\&token=81e6ca84-ad37-42ad-bc13-3074671ac12f)

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

​ 最好还是测一测每种做法的性能，然后从中选出最合适当前场景的方案。

要点：

* 派发队列可以用来表述同步语句，这种做法要比使用`@synchronized`块或`NSLock`对象更简单
* 将同步与异步派发结合起来，可以实现与普通加锁机制一样的同步行为，而这么做却不会阻塞执行异步派发的线程
* 使用同步队列及栅栏快，可以令同步行为更加高效
