欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > NSLock 详解

NSLock 详解

2025/2/21 3:16:44 来源:https://blog.csdn.net/peng_up/article/details/145621053  浏览:    关键词:NSLock 详解

NSLock 是 Objective-C 提供的一种 轻量级互斥锁,用于保证多线程访问共享资源的安全性。相比 @synchronized,它的性能更好,并且提供了更灵活的锁管理方法。

1. NSLock 的基本使用

1)lock和unlock

@interface SafeCounter : NSObject
@property (nonatomic, strong) NSLock *lock;
@property (nonatomic, assign) NSInteger count;
@end@implementation SafeCounter- (instancetype)init {if (self = [super init]) {_lock = [[NSLock alloc] init];}return self;
}- (void)increment {[self.lock lock]; // 加锁self.count += 1;NSLog(@"当前 count: %ld", (long)self.count);[self.lock unlock]; // 解锁
}@end

lock 确保 count 在多个线程访问时不会竞争,避免数据错乱。lock 后必须 unlock,否则会导致死锁。

2)我们还可以使用tryLock(尝试加锁,不阻塞),如果 tryLock 获取到锁,返回 YES,否则返回 NO,不会阻塞线程:

if ([self.lock tryLock]) {// 线程安全代码[self.lock unlock];
} else {NSLog(@"锁已被占用,执行其他逻辑");
}

适用于低优先级任务,避免等待锁导致线程卡住。

3)lockBeforeDate:(限时加锁)

设置超时时间,超过这个时间还拿不到锁,就放弃:

if ([self.lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:2]]) {// 线程安全代码[self.lock unlock];
} else {NSLog(@"超时未获取到锁");
}

适用于有时间敏感性的任务,防止线程长时间等待锁。

2. NSLock 能解决哪些问题?

  1. 防止数据竞争

    • 例如多个线程同时读写 NSMutableArrayNSMutableDictionary 时可能崩溃,NSLock 可以确保一个线程完成操作后,另一个线程才能访问。
  2. 避免死锁

    • NSLock 提供 tryLocklockBeforeDate: 方法,可以防止线程长时间等待锁,降低死锁的风险。
  3. 提高 @synchronized 的性能

    • @synchronized 内部也是基于 NSLock 实现的,但多了一些管理开销,因此 NSLock 更轻量,性能更高。

3、注意事项

避免多个线程交叉锁(死锁)

如果一个线程持有 lock1,等待 lock2,而另一个线程持有 lock2,等待 lock1,就会产生死锁:

[self.lock1 lock];
[self.lock2 lock]; // 这里可能导致死锁
[self.lock2 unlock];
[self.lock1 unlock];

正确做法

  • 尽量保持加锁顺序一致,避免交叉等待。
  • 考虑用 tryLock 失败时执行其他逻辑。

总结

  1. NSLock@synchronized 的更轻量级版本,适合需要手动管理锁的场景。
  2. 支持 tryLocklockBeforeDate:,可以避免死锁,提高程序的健壮性。
  3. 必须保证 lock 之后一定 unlock,避免死锁或线程卡死。
  4. 适用于高频加锁解锁场景,但不支持递归调用(可用 NSRecursiveLock 代替)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词