@synchronized
介绍
@synchronized
是 Objective-C 提供的一种 互斥锁(Mutex),它用于确保一段代码在同一时间只有一个线程能执行,避免多线程访问共享资源时出现数据竞争。
基本语法
@synchronized (lockObject) {
// 需要加锁的代码
}
lockObject
是锁的标识,不同的对象代表不同的锁。- 如果多个线程使用相同的
lockObject
,则@synchronized
会保证同一时间只有一个线程能执行代码块。 - 如果
lockObject
为空 (nil
),不会起到任何加锁效果,代码块仍然会并发执行。
@synchronized
使用场景
1. 保护共享资源
如果多个线程同时修改同一个对象,可能会出现数据竞争问题。例如:
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@property (nonatomic, assign) NSInteger count;
@end
@implementation MyClass
- (void)incrementCount {
@synchronized(self) {
self.count = self.count + 1;
}
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyClass *myObject = [[MyClass alloc] init];
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
// 创建多个线程同时调用 incrementCount 方法
for (int i = 0; i < 1000; i++) {
dispatch_async(concurrentQueue, ^{
[myObject incrementCount];
});
}
// 等待所有任务完成
dispatch_barrier_sync(concurrentQueue, ^{
NSLog(@"Final count: %ld", (long)myObject.count);
});
}
return 0;
}
多次执行结果
Final count: 1000
Final count: 1000
Final count: 1000
如果去掉@synchronized,你会发现结果大多都不是1000
2. 多线程安全地添加元素到数组
多个线程可能同时访问 NSMutableArray
,如果没有同步措施,可能会崩溃:
@interface SafeArray : NSObject
@property (nonatomic, strong) NSMutableArray *array;
@end
@implementation SafeArray
- (instancetype)init {
if (self = [super init]) {
_array = [NSMutableArray array];
}
return self;
}
- (void)addItem:(id)item {
@synchronized (self) {
[self.array addObject:item];
}
}
@end
注意事项
- 性能开销:
@synchronized
会带来一定的性能开销,因为每次进入和退出@synchronized
块都需要进行锁的获取和释放操作。因此,在性能敏感的场景下,应谨慎使用。 - 死锁风险:如果在
@synchronized
块中嵌套使用@synchronized
块,并且使用相同的锁对象,可能会导致死锁。因此,在使用@synchronized
时,要避免出现死锁的情况。