@sychronized(cjobj){} 内部 cjobj 被释放或被设为 nil 不会影响锁的功能,但如果 cjobj 一开始就是 nil,那就会丢失了锁的功能了。
2.NSLock
先看看iOS中NSLock类的.h文件,从代码中可以看出,该类分成了几个子类:NSLock、NSConditionLock、NSRecursiveLock、NSCondition,然后有一个 NSLocking 协议:
@protocol NSLocking
- (void)lock;
- (void)unlock;
@end
虽然 NSLock、NSConditionLock、NSRecursiveLock、NSCondition 都遵循的了 NSLocking 协议,但是它们并不相同。
2.1 NSLock
NSLock 实现了最基本的互斥锁,遵循了 NSLocking 协议,通过 lock 和 unlock 来进行锁定和解锁。
源码内容:
@interface NSLock : NSObject <NSLocking> {
@private
void *_priv;
}
- (BOOL)tryLock;
- (BOOL)lockBeforeDate:(NSDate *)limit;
@property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@end
用法:
- (void)viewDidLoad {
[super viewDidLoad];
[self nslock];
}
- (void)nslock {
NSLock * cjlock = [NSLock new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[cjlock lock];
NSLog(@"线程1加锁成功");
sleep(2);
[cjlock unlock];
NSLog(@"线程1解锁成功");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
[cjlock lock];
NSLog(@"线程2加锁成功");
[cjlock unlock];
NSLog(@"线程2解锁成功");
});
}
控制台输出:
2017-10-19 15:03:58.868708+0800 Thread-Lock[39059:846493] 线程1加锁成功
2017-10-19 15:04:00.872714+0800 Thread-Lock[39059:846493] 线程1解锁成功
2017-10-19 15:04:00.872722+0800 Thread-Lock[39059:846492] 线程2加锁成功
2017-10-19 15:04:00.873000+0800 Thread-Lock[39059:846492] 线程2解锁成功
- (void)nslock {
NSLock * cjlock = [NSLock new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[cjlock lock];
NSLog(@"线程1加锁成功");
sleep(2);
[cjlock unlock];
NSLog(@"线程1解锁成功");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([cjlock tryLock]) {
NSLog(@"线程3加锁成功");
[cjlock unlock];
NSLog(@"线程3解锁成功");
}else {
NSLog(@"线程3加锁失败");
}
});
}
控制台输出:
2017-10-19 15:05:38.627767+0800 Thread-Lock[39118:849171] 线程1加锁成功
2017-10-19 15:05:38.627767+0800 Thread-Lock[39118:849169] 线程3加锁失败
2017-10-19 15:05:40.629969+0800 Thread-Lock[39118:849171] 线程1解锁成功
- (void)nslock {
NSLock * cjlock = [NSLock new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[cjlock lock];
NSLog(@"线程1加锁成功");
sleep(2);
[cjlock unlock];
NSLog(@"线程1解锁成功");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(3);
if ([cjlock tryLock]) {
NSLog(@"线程4加锁成功");
[cjlock unlock];
NSLog(@"线程4解锁成功");
}else {
NSLog(@"线程4加锁失败");
}
});
}










