iOS总结-锁(二)之synchronized的内部实现原理

参考:http://ios.jobbole.com/82826/

关于@synchronized,我们经常应用到写单例的时候,在多线程的情况下,进行加锁操作.
锁是如何传入@synchronized的对象关联上的?如果传入@synchronized的对象在@synchronized的block里面被释放或者被赋值为nil会怎样?
@synchronized block 会变成objc_sync_enter 和 objc_sync_exit成对调用.
iOS总结-锁(二)之synchronized的内部实现原理_第1张图片

有关objc-sync的源码
iOS总结-锁(二)之synchronized的内部实现原理_第2张图片

iOS总结-锁(二)之synchronized的内部实现原理_第3张图片iOS总结-锁(二)之synchronized的内部实现原理_第4张图片

有关objc_sync的源码

@synchronized结构在工作时为传入的对象分配了一个递归锁.
递归锁在被同一线程重复获取时不会产生死锁.你可以在这找到一个它工作原理的精巧案例.和NSRecursiveLock类似.
在objc-sync的源码中,有一个结构体 struct SyncData,包含了object 就是我们传入的对象和一个关联的recursive_mutex_t, 它就是那个跟object关联在一起的锁.每个SyncData也包含一个指向另一个SyncData对象的指针,叫nextData.所以可以把每个SyncData结构体看做是链表中的一个元素.每个SyncData还包含一个threadCount,这个syncData对象中的锁会被一些线程使用或等待,threadCount就是此时这些线程的数量.syncData结构体会被缓存,threadCount= 0 代表这个syncData实例可以被复用.

  Struct SyncList的定义 把SyncData当做是链表中的节点.每个SyncList结构体都有个指向SyncData节点链表头部的指针,也有一个用于防止多个线程对此列表做并发修改的锁.
  sDataLists的声明是一个SyncList结构体数组,大小16.通过哈希算法将传入对象映射到数组上的一个下标.
当调用ovjc_sync_enter(obj)时,用obj内存地址的哈希值查找合适的SyncData,将其上锁.当调用objc_sync_exit(obj),查找合适的SyncData将其解锁
总结:
    1.当调用synchronzied的每个对象,runtime都会为其分配一个递归锁并存储在哈希表中
    2.如果在synchronzied内部对象被释放或为nil,会执行类似objc_sync_nil的空方法
    3.不要想synchronzied block 传入nil , 如果为nil ,则将会从代码中线程安全
 

你可能感兴趣的:(iOS)