问题:任务A,B,C先执行A和B再执行C可以怎么实现(group,条件锁,barrier)
方案1、group 通过创建信号量访问资源数量为1,然后通过wait和sign顺序执行group内线程。
方案2、NSConditionLock,通过控制创建条件和解锁条件,顺序执行线程。
let lock = NSConditionLock.init(condition: 3)
DispatchQueue.global().async {
lock.lock(whenCondition: 3)
print("A")
lock.unlock(withCondition: 2)
}
DispatchQueue.global().async {
lock.lock(whenCondition: 2)
print("B")
lock.unlock(withCondition: 1)
}
DispatchQueue.global().async {
lock.lock(whenCondition: 1)
print("C")
lock.unlock()
}
方案3、barrier 允许在一个并发队列中创建一个同步点。当在并发队列中遇到一个barrier, 他会延迟执行barrier的block,等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行。
二、条件锁
1、条件锁定义
@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
转载地址:
iOS锁系列-NSConditionLock条件锁