美文网首页ios实用技术
iOS锁系列-NSConditionLock条件锁

iOS锁系列-NSConditionLock条件锁

作者: lltree | 来源:发表于2018-04-17 17:25 被阅读249次
    
    @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条件锁

        本文链接:https://www.haomeiwen.com/subject/xbbekftx.html