美文网首页iOS开发攻城狮的集散地iOS 面试题IOS
22·iOS 面试题·使用 atomic 一定是线程安全的吗?

22·iOS 面试题·使用 atomic 一定是线程安全的吗?

作者: pengxuyuan | 来源:发表于2018-11-22 11:38 被阅读2次

    前言

    atomic/nonatomic 是属性修饰符之一,atomic 代表原子性,nonatomic 代表非原子性;原子性是防止方法调用到一半其它操作再次进入该方法,导致出现异常情况。

    atomic 和 nonatomic 区别以及实现

    首先我们知道 atomic 代表原子性,nonatomic 代表非原子性;用这两个修饰符来修饰属性,区别主要在于属性的 getter/setter 方法:atomic 会对 setter 方法进行加锁,nonatomic 不会对 setter 方法加锁。

    atomic 修饰的属性,在 setter 方法中使用 @synchronized 加锁来确保原子操作,但是 @synchronized 相比于其它类型的锁,性能是最低效的,因为除了加锁之外,额外还会设置异常处理机制,性能消耗较大。这里就是为什么平时开发中很少使用 atomic 来修饰属性。

    atomic 与 nonatomic 在 getter/setter 方法区别如下:

    //interface
    @property(nonatomic,strong)UIImage *icon;//nonatomic
    @property(strong)UIImage *icon1;//atomic
    
    //set
    -(void)setIcon:(UIImage *)icon
    {
        if(_icon != icon)
        {
            [_icon release];
            _icon = [icon retain];
        }
    }
    
    //set
    -(void)setIcon1:(UIImage *)icon1
    {
        //同步代码块
        @synchronized (self) {
            
            if(_icon1 != icon1)
            {
                [_icon1 release];
                _icon1 = [icon1 retain];
            }
        }
    }
    

    atomic 不保证线程安全

    atomic 只会保证 setter/getter 方法是原子操作的,防止方法调用到一半其它操作再次进入该方法,导致出现异常情况。即原子性保证你访问的时候给你返回一个完好无损的对象,但是不会保证线程安全,这里有个经典的例子:

    //如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。
    

    iOS 几种锁的性能差异

    前面提到了 @synchronized 比其它锁性能低,这里就简单说一下 iOS 中的不同锁的性能差异,常见的锁有:@synchronized、NSLock、pthread mutexes、OSSpinLock;这篇 @synchronized, NSLock, pthread, OSSpinLock showdown, done right 文章对几种锁进行了实验,得出:@synchronized 是最慢的,OSSpinLock 是最快的;

    @synchronized 性能差的原因就是前面提到过的:除了加锁操作之外,还需要设置异常处理机制。NSLock 是对 pthread mutexes 的 Objective-C 封装;OSSpinLock 目前已经废弃,可以使用 os_unfair_lock() 来进行加锁。

    总结

    现在知道 atomic 是不能保证线程安全的,还简单了解了 iOS 几种锁的性能差异;在总结这个面试知识点时,主要涉及到了线程编程,看了官方 Threading Programming Guide 文档,本来我也写了翻译总结,但是发现了一篇非常优秀的总结:Threading Programming Guide(1),大家可以去看看。

    里面有很多有趣的知识点,以后慢慢跟大家一起学习,例如:

    • Idle-time Notification
    • 如何创建进程
    • 利用 Run Loop 进行跨线程之间通讯
    • 分离式线程与非分离式线程的区别
    • ....

    参考文献

    @synchronized, NSLock, pthread, OSSpinLock showdown, done right

    iOS中atomic和nonatomic区别及内部实现

    Atomic vs. Non-Atomic Operations

    Threading Programming Guide

    Threading Programming Guide(1)

    相关文章

      网友评论

        本文标题:22·iOS 面试题·使用 atomic 一定是线程安全的吗?

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