InterView-多线程-1.常用线程同步安全方案

146 阅读2分钟

1. 使用 GCD(Grand Central Dispatch)

通过串行队列或同步锁保证线程安全。

objc
复制代码
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serialQueue", DISPATCH_QUEUE_SERIAL);

- (void)threadSafeMethod {
    dispatch_sync(serialQueue, ^{
        // 线程安全的操作
        self.sharedResource = @"Updated Value";
    });
}

2. 使用 NSLock

通过显式的锁机制防止线程竞争。

objc
复制代码
NSLock *lock = [[NSLock alloc] init];

- (void)threadSafeMethod {
    [lock lock];
    // 线程安全的操作
    self.sharedResource = @"Updated Value";
    [lock unlock];
}

3. 使用 @synchronized

Objective-C 提供的同步机制,简单易用,但性能不如 NSLock。

objc
复制代码
- (void)threadSafeMethod {
    @synchronized (self) {
        // 线程安全的操作
        self.sharedResource = @"Updated Value";
    }
}

4. 使用 OSSpinLock(已弃用)

适用于短时间锁定的场景,但不推荐在现代开发中使用(可能有优先级反转问题)。

objc
复制代码
OSSpinLock lock = OS_SPINLOCK_INIT;

- (void)threadSafeMethod {
    OSSpinLockLock(&lock);
    // 线程安全的操作
    self.sharedResource = @"Updated Value";
    OSSpinLockUnlock(&lock);
}

5. 使用 pthread_mutex

底层实现的线程锁,更加灵活,但需要手动管理。

objc
复制代码
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

- (void)threadSafeMethod {
    pthread_mutex_lock(&mutex);
    // 线程安全的操作
    self.sharedResource = @"Updated Value";
    pthread_mutex_unlock(&mutex);
}

6. 使用 NSRecursiveLock

支持嵌套锁定的锁,适用于递归调用的场景。

objc
复制代码
NSRecursiveLock *recursiveLock = [[NSRecursiveLock alloc] init];

- (void)threadSafeMethod {
    [recursiveLock lock];
    // 线程安全的操作
    self.sharedResource = @"Updated Value";
    [recursiveLock unlock];
}

7. 使用 Atomic 属性

通过 atomic 属性自动生成线程安全的 gettersetter,但无法保证复合操作的线程安全。

objc
复制代码
@property (atomic, strong) NSString *sharedResource;

// 自动生成的线程安全访问
self.sharedResource = @"Updated Value";

8. 使用 Dispatch Barriers

适用于并发队列,保证写操作的线程安全。

objc
复制代码
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

- (void)threadSafeWrite {
    dispatch_barrier_async(concurrentQueue, ^{
        self.sharedResource = @"Updated Value";
    });
}

- (void)threadSafeRead {
    dispatch_async(concurrentQueue, ^{
        NSLog(@"%@", self.sharedResource);
    });
}

9. 使用 Atomic Operations

通过操作系统提供的原子操作函数,直接对数据进行线程安全的操作。

objc
复制代码
OSAtomicIncrement32(&counter);

10. 使用 @property 的 Weak 机制

对对象的弱引用,避免因多线程竞争导致的崩溃。

objc
复制代码
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"%@", weakSelf);
});

以上是常见的线程安全实现方式,可根据不同场景选择合适的方案。