iOS-@synchronized的简单实用

@synchronized 结构所做的事情跟锁lock类似:它防止不同的线程同时执行同一段代码。但在某些情况下,相比于使用 NSLock创建锁对象、加锁和解锁来说,@synchronized用着更方便,可读性更高。

@synchronized 的例子

@implementation ThreadSafeQueue
{
    NSMutableArray *_elements;
    NSLock *_lock;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        _elements = [NSMutableArray array];
        _lock = [[NSLock alloc] init];
    }
    return self;
}
- (void)push:(id)element
{
    [_lock lock];
    [_elements addObject:element];
    [_lock unlock];
}
@end

i
上面的 ThreadSafeQueue类有个init方法,它初始化了一个 _elements数组和一个 NSLock实例。
这个类还有个 push:方法,它先获取锁、然后向数组中插入元素、最终释放锁。可能会有许多线程同时调用 push:方法,但是[_elements addObject:element]这行代码在任何时候将只会在一个线程上运行。步骤如下:
1 线程 A 调用 push:方法
2 线程 B 调用 push:方法
3 线程 B 调用 [_lock lock]- 因为当前没有其他线程持有锁,线程 B 获得了锁
4 线程 A 调用 [_lock lock],但是锁已经被线程 B 占了所以方法调用并没有返回-这会暂停线程 A 的执行
5 线程 B 向 _elements添加元素后调用 [_lock unlock]。当这些发生时,线程 A 的[_lock lock]方法返回,并继续将自己的元素插入 _elements

我们可以用 @synchronized结构更简要地实现这些:

@implementation ThreadSafeQueue
{
    NSMutableArray *_elements;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        _elements = [NSMutableArray array];
    }
    return self;
}
- (void)increment
{
    @synchronized (self) {
        [_elements addObject:element];
    }
}
@end

在前面的例子中,”synchronized block”[_lock lock][_lock unlock]效果相同。你可以把它当成是锁住 self,仿佛 self就是个 NSLock
锁在左括号 {后面的任何代码运行之前被获取到,在右括号 }
后面的任何代码运行之前被释放掉。这爽就爽在妈妈再也不用担心我忘记调用 unlock了!
你可以给任何 Objective-C 对象上加个 @synchronized。那么我们也可以在上面的例子中用 @synchronized(_elements)来替代 @synchronized(self),效果是相同的。

转自cocoa
@synchronized官方文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容