@protocol NSLocking
//试着获取锁,阻塞线程的执行直到获取到锁
- (void)lock;
//解锁
- (void)unlock;
@end
@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
eg:
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程1");
sleep(3);//模拟耗时操作
[lock unlock];
NSLog(@"线程1解锁成功");
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1); //简单实现线程2在线程1后出队执行
[lock lock];
NSLog(@"线程2");
[lock unlock];
});
print:通过锁,保证线程1先执行,再执行线程2
2019-12-02 22:16:32.613992+0800 Task[5507:349352] 线程1
2019-12-02 22:16:32.614454+0800 Task[5507:349352] 线程1解锁成功
2019-12-02 22:16:32.614619+0800 Task[5507:349353] 线程2
eg:
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程1");
sleep(3);
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
if ([lock tryLock]) {
NSLog(@"线程2");
[lock unlock];
} else {
NSLog(@"尝试加锁失败");
}
});
print: tryLock 并不会阻塞线程。[lock tryLock] 能获取锁立即返回 YES,不能获取立即返回 NO,然后都会执行后续代码。
2019-12-02 22:28:09.480585+0800 Task[5593:356540] 线程1
2019-12-02 22:28:10.480705+0800 Task[5593:356541] 尝试加锁失败
eg:
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程1");
sleep(3);
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
if ([lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]) {
NSLog(@"线程2");
[lock unlock];
} else {
NSLog(@"尝试加锁失败");
}
});
print: lockBeforeDate: 方法会在所指定 Date 之前尝试获取锁,会阻塞线程,如果在指定时间之前都不能获取,则返回 NO,指定时间之前能获取锁,则返回 YES。
2019-12-02 22:31:52.172769+0800 Task[5649:359642] 线程1
2019-12-02 22:31:54.172128+0800 Task[5649:359643] 尝试加锁失败