@interface NSConditionLock : NSObject <NSLocking> {
@private
void *_priv;
}
//初始化一个NSConditionLock对象
- (instancetype)initWithCondition:(NSInteger)condition NS_DESIGNATED_INITIALIZER;
@property (readonly) NSInteger condition; //锁的条件
//满足条件时加锁
- (void)lockWhenCondition:(NSInteger)condition;
- (BOOL)tryLock;
//如果接收对象的condition与给定的condition相等,则尝试获取锁,不阻塞线程
- (BOOL)tryLockWhenCondition:(NSInteger)condition;
//解锁后,重置锁的条件
- (void)unlockWithCondition:(NSInteger)condition;
- (BOOL)lockBeforeDate:(NSDate *)limit;
//在指定时间前尝试获取锁,若成功则返回YES 否则返回NO
- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;
@property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@end
代码示例:
//主线程中
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:0];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lockWhenCondition:1];
NSLog(@"线程1");
sleep(2);
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);//以保证让线程2的代码后执行
if ([lock tryLockWhenCondition:0]) {
NSLog(@"线程2");
[lock unlockWithCondition:2];
NSLog(@"线程2解锁成功");
}
else {
NSLog(@"线程2尝试加锁失败");
}
});
//线程3
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// sleep(2);//以保证让线程2的代码后执行
if ([lock tryLockWhenCondition:2]) {
NSLog(@"线程3");
[lock unlock];
NSLog(@"线程3解锁成功");
}
else {
NSLog(@"线程3尝试加锁失败");
}
});
//线程4
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// sleep(3);//以保证让线程2的代码后执行
[lock lockWhenCondition:2];
NSLog(@"线程4");
[lock unlockWithCondition:1];
NSLog(@"线程4解锁成功");
});
打印结果:
2018-04-17 16:59:26.995255+0800 NSLock测试[48379:5945905] 线程3尝试加锁失败
2018-04-17 16:59:28.000120+0800 NSLock测试[48379:5945903] 线程2
2018-04-17 16:59:28.000791+0800 NSLock测试[48379:5945903] 线程2解锁成功
2018-04-17 16:59:28.000851+0800 NSLock测试[48379:5945904] 线程4
2018-04-17 16:59:28.001999+0800 NSLock测试[48379:5945904] 线程4解锁成功
2018-04-17 16:59:28.002044+0800 NSLock测试[48379:5945902] 线程1
结果说明:
1 初始化一个条件锁,条件为0
2 由于线程1 和线程4条件不满足,所以循环一段时间休眠,等待满足条件满足时唤醒;线程3尝试加锁,不会阻塞线程,但是条件不满足所以直接休眠;线程2休眠1秒后尝试加锁。满足条件所以加锁成功;
3 线程2伴随重置加锁条件2进行解锁;
4 此时线程4满足条件,系统唤醒进行加锁,并且重置加锁条件14
5 此时线程1满足条件,系统唤醒进行加锁,并且解锁,此时条件为1