iOS各种锁的对比
为什么要引入锁?这是每个在学习ios锁的同学都会有的疑问。简单来说,ios语言是多线程的,当多个线程操作一个对象,且这个对象的操作要求是有序的时候,就需要的这个对象加锁。
eg:
ios中存在一个数据库
a/b/c/d业务都会像这个业务中存取数据
a/b/c/d业务操作是异步的
就会存在这样一个情况,a在根据条件删除数据库中的数据,b在向数据库中添加数据。a/b是异步执行的,就可能a在执行的时候,b添加了元素,a继续执行,b添加的元素被删除。这样就与a执行完成在执行b冲突。
这个时候就引入了锁的概念
eg:
生成一个锁保护数据库这个对象
只有拥有当锁打开的时候,该对象才能备操作
各种锁的性能的对比
这里给出了几个性能性能对比的blog,详细的介绍了各种lock的使用场景以及时间消耗
各种锁的使用场景
- NSLock
相信大家接触最多的就是NSLock这个锁了,这个就不多用多说了。只要被NSLock锁中保护的对象,修改它只能在unlock的状态下
NSCondition
从名字中可以知道,这是一个条件锁。主要的特点其实是在
wait
和signal
这两个函数。当条件不满足时,wait,这个锁在了一个等待的状态,当我们再想让这个锁执行时,signal一个信号,中断的函数就会继续执行了(void)wait; 挂起线程
(BOOL)waitUntilDate:(NSDate *)limit; 线程挂起到指定时间
(void)signal; 任意通知一个线程
(void)broadcast; 通知所用等待的线程
eg:
- 网络图片加载,下载图片时子线程wait
- 当网络图片下载完成之后signal,中断wait调用主线程重新渲染UI
NSConditionLock
从名字上看也是一个条件所,但是和之前的NSCondition有什么区别呢,我们看一下API,初始化条件锁,注意这个condition
- (instancetype)initWithCondition:(NSInteger)condition NS_DESIGNATED_INITIALIZER;
初始化中的condition,readonly
- property (readonly) NSInteger condition;
当条件满足时加锁
- (void)lockWhenCondition:(NSInteger)condition;
尝试加锁,返回值为BOOL,这里先做判断为好
- (BOOL)tryLock;
当满足条件时尝试加锁
- (BOOL)tryLockWhenCondition:(NSInteger)condition;
当满足条件时尝试解锁
- (void)unlockWithCondition:(NSInteger)condition;
在指定时间之前加锁
- (BOOL)lockBeforeDate:(NSDate *)limit;
在指定时间之前条件满足时加锁
- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;
其实他的API已经解释了这个锁的使用环境
NSRecursiveLock
从名字中大约知道这个锁实在递归中使用的。那么这个锁的用处在哪里?
@property (nonatomic, strong) NSLock *lock;
@property (nonatomic, strong) NSRecursiveLock *recursiveLock;(void)viewDidLoad {
[super viewDidLoad];
[self recursiveFunction:100];
}(void)recursiveFunction:(NSInteger)condition {
[self.lock lock];
if (condition == 0) {return;
} else {
[self recursiveFunction:condition-1];
}
[self.lock unlock];
}
上面的函数执行的时候会崩溃,NSLock无法在同一线程下,没有unlock就再次持有这个锁,为了满足递归时对该对象的保护出现了NSRecursiveLock将self.lock替换成self.recursiveLock就可以执行了
为什么换成了递归所就没有问题了呢?
那是因为,NSRecursiveLock类定义的锁可以在同一线程多次获得,而不会造成死锁。一个递归锁会跟踪它被多少次成功获得了。每次成功的获得该锁都必须平衡调用锁住和解锁的操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得。
OSSpinLock
现在已不再推荐使用 请看链接
dispatch_barrier_async
这里有一篇很好的文章介绍
@synchronized
这也是一个互斥锁,相当于NSLock的封装版。相信大家用的也不少,虽然简化了很多,但是不推荐大家使用,自己在创建锁资源是比较耗时
总结
在对比了所有的锁之后,相信大家在面对资源读取的时候会有自己的初步判断了。至少我在搜集了这些资料之后里了解了更多,不是吗