iOS - 互斥锁&&自旋锁 多线程安全隐患
一、多线程安全隐患
资源共享
一块资源可能会被多个线程共享,也就是多个线程可能会访问到一块资源
比如多个线程访问同一个对象,同一个变量,同一个文件。
当多线程访问同一块资源的时候,很容易引发数据错乱和数据安全问题
二、原子和非原子属性
1>OC 在定义属性的时候有nonatomic和atomic两种选择
* atomic:原子属性,为 setter 方法加锁
* nonatomic:非原子属性,不会为 setter 方法加锁
普通情况下都是在主线程做操作,所以一般都不会加锁。
对比:
* atomic:线程安全,需要消耗大量的资源
* nonatomic:非线程安全,适合内存小的移动设备
2>synchronized 与 atomic
* synchronized:互斥锁
* atomic:自旋锁
共同点:都能保证同一时刻只能有一个线程操作锁住的代码
区别:
互斥锁:当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会进入睡眠状态等待任务执行完毕,当上一个线程的任务执行完毕,下一个线程会. 自动唤醒然后执行任务。
自旋锁:当上一个线程的任务没有执行完毕的时候(被锁住),那么下一个线程会一直等待(不会睡眠),当上一个线程的任务执行完毕,下一个线程会立即执行。
自旋锁应用场景:比较适合做一些不耗时的操作
三、互斥锁
· 注意点:
- 如果多线程访问同一个资源,那么必须使用同一把锁才能锁住
- 在开发中,尽量不要加锁,能在服务端做尽量在服务端做,如果必须要加锁,一定要记住,锁的范围不能太大,哪里有安全隐患就加在哪里。
技巧:因为必须使用同一把锁,开发中如果需要加锁,直接使用 self 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @synchronized ( self ) { //线程1进来之后,锁住,2和3都再外面等待 //1、查询剩余的票数 NSUInteger count = self.totalCount; //2、判断是否还有余票 //2.1卖票 //3 、提示客户,没有票了 if (count>0) { [ NSThread sleepForTimeInterval:0.1]; self .totalCount = count-1; NSLog (@ "%@卖了一张票,还剩%zd票" ,[ NSThread currentThread].name, self .totalCount); } else { NSLog (@ "没票了" ); break ; } } //解锁 |
四、自旋锁
注意点:
只会给 setter 方法加锁,并不会给getter方法加锁。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)