美文网首页
iOS-@synchronized的简单实用

iOS-@synchronized的简单实用

作者: iSongWei | 来源:发表于2017-01-05 16:24 被阅读453次

    @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官方文档

    相关文章

      网友评论

          本文标题:iOS-@synchronized的简单实用

          本文链接:https://www.haomeiwen.com/subject/tdezvttx.html