这是我参与8月更文挑战的第23天,活动详情查看: 8月更文挑战
我们接着上一篇文章iOS底层分析-锁(一)继续分析锁;
synchronized中SyncData的结构
我们先来看一下SyncData输一个什么样的数据结构:

SyncData是一个结构体类型的数据;我们注意到其结构体内部有一个SyncData* nextData的成员变量,看到这里,我们会下意识的想起链表。因为只有有一个nextData,所以它有可能是一个单向链表;DisguisedPtr<objc_object> object;我们在学习关联对象的时候看到过这样的代码,是一个ptr类型的封装;threadCount有多少线程正在使用这个block;recursive_mutex_t mutex;是一个递归锁,只能递归使用,但是不能多线程的递归;
知道了SyncData的数据结构之后,接下来我们分析id2data方法;
synchronized的数据结构
tls线程相关知识补充
在讲id2data方法之前,我们需要补充一下tls的相关知识;
线程局部存储Thread Local Storage, TLS:是操作系统为线程单独提供的私有空间,通常只有有限的容量。Linex系统下通常通过pthread库中的一下几个函数进行操作:
- pthread_key_create()
- pthread_getspecific()
- pthread_setspecific()
- pthread_key_delete()
id2data方法分析
我们点击进入id2data方法的实现,这个方法相当复杂,那么我们关闭一下复杂的操作,从整体上来看一下这个方法:

我们可以发现,id2data方法主要进行了以下操作:
data存储- 开辟内存空间,给
SyncData类型的result赋值; lock()和unlock()是保证方法体内部进行内存开辟时的线程安全;跟外部的锁没有关系;- 最终返回一个
result;
接下来,我们进行详细的分析:
spinlock_t *lockp = &LOCK_FOR_OBJ(object);通过宏#define LOCK_FOR_OBJ(obj) sDataLists[obj].lock和object获取了一把锁;SyncData **listp = &LIST_FOR_OBJ(object);通过宏#define LIST_FOR_OBJ(obj) sDataLists[obj].data和object获取了一个SyncData;
那么我们不免有疑问:获取listp有有什么用呢?宏定义中的sDataLists又是什么东西呢?
sDataLists结构分析
我们之前学习哈希表的时候,会根据哈希函数获取下标,如果发生冲突再哈希;那么现在除了再哈希之后,还有一种拉链法;
首先,sDataLists是一个全局性的静态变量,也是一张哈希表,在整个SyncData的处理过程中都会使用它;标的泛型是SyncList,SyncList中也含有SyncData:

为了分析其具体结构,接下来我们使用下边代码,结合lldb进行分析:

需要注意的是,此处我们在main方法最后使用了do-while的一个死循环来卡着App,否则直接直接程序就运行结束了;
我们使用p sDataLists来查看sDataLists的数据结构,打印之后我们发现sDataLists结构中含有一个array的结构,而这个array有64个元素,因为我们使用的是模拟器,所以打印之后有64个结构,而此处的64来源于:

模拟器有64个,真机是有8个;
接下来,我们让id2data执行完毕一次(在sDataLists中存入一个SyncData),断住第二次执行的流程:

发现,存储的第一个SyncData对象,保存在了23的位置(因为是哈希结构,所以第一次并不是从0开始,而是通过一个计算出的下标开始存储);
其结构如下:

SyncData在SyncList中;SyncList在array表中;
其数据结构大致如下(我们以真机8个来进行图示):

我们在使用@synchronized时,经常喜欢传self,那么如果前后两次调用@synchronized时都传的是self,那么前后两个self,生成的两个SyncData将会产生哈希冲突,SyncList作为链表形式,其存储结构将会变为:

- 同一个
self生成的两个SyncData并不会两两冲突,将会存储进链表SyncList中; - 两个
SyncData具备相似性;
链表结构并不方便查询,而SyncData并不需要查询,只需要加锁解锁,也就是只需要增删操作(拉链法);
未完待续……























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)