版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.05.21 |
前言
ios中有好几种锁,比如自旋锁,互斥锁,信号量等等,锁其实是多线程数据安全的一种解决方案,作用就是保证同一时间只有一个线程访问和改变某些敏感数据,这些锁的性能也是差别很大,最近看了几个技术大牛的技术博客,我才发现我以前对锁的理解太肤浅了,心虚的赶紧找资料又开始了深入学习,然后整理出来。前面介绍了几种锁:
1. ios开发中的几种锁(一)
2. ios开发中的几种锁(二)
3. ios开发中的几种锁(三)
这篇接着讲其他的几种锁。
详情
一、synchronized 条件锁
@synchronized 相信大家应该都熟悉,它的用法应该算这些锁中最简单的。
看代码
1. JJSynchronizedVC.h
#import <UIKit/UIKit.h>
@interface JJSynchronizedVC : UIViewController
@end
2. JJSynchronizedVC.m
#import "JJSynchronizedVC.h"
@interface JJSynchronizedVC ()
@end
@implementation JJSynchronizedVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
[self aboutSynchronized];
}
#pragma mark - Object Private Function
- (void)aboutSynchronized
{
int __block num = 5;
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized (self)
{
num = num + 1;
NSLog(@"num1=%d",num);
NSLog(@"线程1");
}
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized (self)
{
num = num + 1;
NSLog(@"num2=%d",num);
NSLog(@"线程2");
}
});
}
@end
更多关于synchronized锁的可以参考《 关于 @synchronized,这儿比你想知道的还要多》
二、NSConditionLock 条件锁
我们还是先看一下API
@interface NSConditionLock : NSObject <NSLocking> {
@private
void *_priv;
}
- (instancetype)initWithCondition:(NSInteger)condition NS_DESIGNATED_INITIALIZER;
@property (readonly) NSInteger condition;
- (void)lockWhenCondition:(NSInteger)condition;
- (BOOL)tryLock;
- (BOOL)tryLockWhenCondition:(NSInteger)condition;
- (void)unlockWithCondition:(NSInteger)condition;
- (BOOL)lockBeforeDate:(NSDate *)limit;
- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;
@property (nullable, copy) NSString *name NS_AVAILABLE(10_5, 2_0);
@end
相比于 NSLock 多了个 condition 参数,我们可以理解为一个条件标示。
下面我们就看代码
1. JJNSCondationLockVC.h
#import <UIKit/UIKit.h>
@interface JJNSCondationLockVC : UIViewController
@end
2. JJNSCondationLockVC.m
#import "JJNSCondationLockVC.h"
@interface JJNSCondationLockVC ()
@end
@implementation JJNSCondationLockVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
[self aboutNSCondationLock];
}
#pragma mark - Object Private Function
- (void)aboutNSCondationLock
{
NSConditionLock *condationLock = [[NSConditionLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if([condationLock tryLockWhenCondition:0]){
NSLog(@"线程1");
[condationLock unlockWithCondition:1];
}else{
NSLog(@"失败");
}
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[condationLock lockWhenCondition:3];
NSLog(@"线程2");
[condationLock unlockWithCondition:2];
});
//线程3
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[condationLock lockWhenCondition:1];
NSLog(@"线程3");
[condationLock unlockWithCondition:3];
});
}
@end
下面看输出结果
2017-05-21 23:42:52.873 lock[4843:255681] 线程1
2017-05-21 23:42:52.874 lock[4843:255670] 线程3
2017-05-21 23:42:52.875 lock[4843:255671] 线程2
由上可知,我们在初始化 NSConditionLock 对象时,给了他的标示为 0;执行 tryLockWhenCondition:时,我们传入的条件标示也是 0,所 以线程1 加锁成功;执行 unlockWithCondition:时,这时候会把condition由 0 修改为 1;因为condition 修改为了 1, 会先走到 线程3,然后 线程3 又将 condition 修改为 3,最后走了线程2 的流程。
从上面的结果我们可以发现,NSConditionLock 还可以实现任务之间的依赖。
相关参考技术博客
1.iOS 开发中的八种锁(Lock)
2.不再安全的 OSSpinLock
3. NSRecursiveLock递归锁的使用
4.关于dispatch_semaphore的使用
5.实现锁的多种方式和锁的高级用法
后记
这回八种锁的简单介绍以及使用方法就都结束了,以后会添加对这八种方法的深入理解。待续,谢谢大家的支持。