美文网首页IOS开发知识点
iOS Synchronized的内部实现原理

iOS Synchronized的内部实现原理

作者: 金字塔的AI | 来源:发表于2019-07-30 21:10 被阅读0次

    任何时候探究一些原理都得从源码抓起 objc_sync

    关于@synchronized,

    使用场景一:写单例的时候,

    使用场景二:在多线程的情况下,进行加锁操作.

    那么锁是如何传入@synchronized的对象关联上的?✨✨✨✨✨✨

    如果传入@synchronized的对象在@synchronized的block里面被释放或者被赋值为nil会怎样?✨✨✨✨✨✨

    @synchronized block 会变成objc_sync_enter 和 objc_sync_exit成对调用.✨✨✨✨✨✨

    ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
    @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.通过哈希算法将传入对象映射到数组上的一个下标.✨✨✨✨✨✨

    当调用objc_sync_enter(obj)时,用obj内存地址的哈希值查找合适的SyncData,将其上锁.当调用objc_sync_exit(obj),查找合适的SyncData将其解锁 ✨✨✨✨✨✨

    总结:

    1.当调用synchronzied的每个对象,runtime都会为其分配一个递归锁并存储在哈希表中

    2.如果在synchronzied内部对象被释放或为nil,会执行类似objc_sync_nil的空方法

    3.不要想synchronzied block 传入nil , 如果为nil ,则将会从代码中线程安全

    最后,思考:如何自己实现synchronized锁呢?边看源码边敲寻找灵感

    参考链接:https://bestswifter.com/ios-lock/

      pthread_mutex_lock 源码参考

      ThreadSafety

     关于Synchronized

    相关文章

      网友评论

        本文标题:iOS Synchronized的内部实现原理

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