@synchronized的使用

发布于:2025-02-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

@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 时,要避免出现死锁的情况。