浅谈iOS中的锁的介绍及使用

2020-01-21 02:17:48于海丽

@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加锁失败");
    }
  });
}