面试题答案
一键面试使用锁机制确保内存安全
@synchronized
:- 用法:在访问和修改共享Objective - C对象属性的代码块前后,使用
@synchronized
包裹。例如:
- 用法:在访问和修改共享Objective - C对象属性的代码块前后,使用
@property (nonatomic, assign) NSInteger sharedValue;
- (void)threadSafeModifyValue {
@synchronized(self) {
self.sharedValue++;
}
}
- **原理**:`@synchronized`会为传入的对象(通常是`self`,即当前类实例)生成一个互斥锁。当一个线程进入`@synchronized`块时,它会获取这个锁,其他线程就必须等待锁被释放才能进入相同的`@synchronized`块。
2. NSLock
:
- 用法:创建一个NSLock
实例,并在访问和修改共享属性前后调用lock
和unlock
方法。例如:
@property (nonatomic, assign) NSInteger sharedValue;
@property (nonatomic, strong) NSLock *myLock;
- (instancetype)init {
self = [super init];
if (self) {
_myLock = [[NSLock alloc] init];
}
return self;
}
- (void)threadSafeModifyValue {
[self.myLock lock];
self.sharedValue++;
[self.myLock unlock];
}
- **原理**:`NSLock`是一个简单的互斥锁。调用`lock`方法时,如果锁可用,线程获取锁并继续执行;如果锁已被其他线程持有,当前线程会被阻塞,直到锁被释放并成功获取。
不同锁机制的优缺点
@synchronized
:- 优点:
- 简单易用:语法简洁,不需要显式创建锁对象,只需要传入要同步的对象即可。
- 自动释放锁:当代码块执行完毕,锁会自动释放,无需手动管理,减少了忘记释放锁导致死锁的风险。
- 缺点:
- 性能开销较大:
@synchronized
内部使用了哈希表来管理锁,每次进入和离开代码块都有一定的性能开销,尤其是在高并发场景下。 - 锁粒度较大:它会锁定整个对象,可能导致不必要的线程等待,降低并发性能。
- 性能开销较大:
- 优点:
NSLock
:- 优点:
- 性能较好:相比于
@synchronized
,NSLock
是更轻量级的锁,在简单场景下性能更优。 - 锁粒度可灵活控制:可以根据需要在更细粒度的代码块上使用锁,提高并发性能。
- 性能较好:相比于
- 缺点:
- 手动管理锁:需要手动调用
lock
和unlock
方法,容易出现忘记释放锁的情况,从而导致死锁。 - 代码复杂度增加:需要额外创建和管理锁对象,增加了代码的复杂度。
- 手动管理锁:需要手动调用
- 优点: