美文网首页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)

相关文章

  • atomic与线程安全

    本篇文章采用的源码是objc4-781版本 使用atomic一定是线程安全的吗? atomic不是绝对的线程安全。...

  • 题库整理(一)

    1.atomic和nonatomic的区别?atomic一定是线程安全的吗?atomic如何实现atomic? a...

  • iOS 面试提(二)

    使用atomic一定是线程安全的吗? 不是,atomic仅针对于getter和setter方法调用的时候,此时at...

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

    前言 atomic/nonatomic 是属性修饰符之一,atomic 代表原子性,nonatomic 代表非原子...

  • 2020-09-16

    2020年iOS面试 记录一下自己遇到的面试题 百度: 1.atomic是不是线程安全的?怎么保证线程安全? 2....

  • 面试题收集

    11饿了么面试题: 你了解哪些iOS底层知识 * automic一定是线程安全的吗 * iOS中的消息传递是怎么一...

  • 使用atomic一定是线程安全的吗?

    一般当我们想要保证对象属性的线程安全的时候可以在定义属性的时候用 atomic 关键字来修饰,那么这篇文章让我们来...

  • 使用atomic一定是线程安全的吗?

    线程安全 1.线程安全的概念多条线程同时工作的情况下,通过运用线程锁,原子性等方法避免多条线程因为同时访问同一快内...

  • 使用atomic一定是线程安全的吗?

    这个问题很少遇到,但是答案当然不是。atomic在set方法里加了锁,防止了多线程一直去写这个property,造...

  • ios的atomic一定是线程安全的吗?

    atomic修饰的属性一定是线程安全的吗?这个问题其实包括两个块内存,一个是栈区指针的内存A,一个是堆区对象占用的...

网友评论

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

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