atomic不能足够安全(effective objective-c2.0第6条和41条)

  • atomic使用了原子性,保证了线程安全,事实真的是这样吗?
    nonatomic的内存管理语义是非原子性的,非原子性的操作本来就是线程不安全的,而atomic的操作是原子性的,但是并不意味着它是线程安全的,它会增加正确的几率,能够更好的避免线程的错误,但是它仍然是线程不安全的。

    当使用nonatomic的时候,属性的setter,getter操作是非原子性的,所以当多个线程同时对某一属性读和写操作时,属性的最终结果是不能预测的。

    当使用atomic时,虽然对属性的读和写是原子性的,但是仍然可能出现线程错误:当线程A进行写操作,这时其他线程的读或者写操作会因为该操作而等待。当A线程的写操作结束后,B线程进行写操作,然后当A线程需要读操作时,却获得了在B线程中的值,这就破坏了线程安全,如果有线程C在A线程读操作前release了该属性,那么还会导致程序崩溃。所以仅仅使用atomic并不会使得线程安全,我们还要为线程添加lock来确保线程的安全。
    也就是要注意:atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的。如下列所示:
    比如:@property(atomic,strong)NSMutableArray *arr;

如果一个线程循环的读数据,一个线程循环写数据,那么肯定会产生内存问题,声明一个NSMutableArray的原子属性stuff,此时self.arr 和self.arr = otherarr都是线程安全的。如使用[self.arr objectAtIndex:index]就不是线程安全的,这和setter、getter没有关系,一个线程在连续多次读取某属性值的间隔过程中若又别的线程同时在改写该值,那么即便将属性声明为atomic也还是会读到不同的属性值。。好的解决方案就是加锁。

atomic使用同步锁开销比较大,atomic要比nonatomic慢大约20倍。一般如果条件允许,我们可以让服务器来进行加锁操作。

解决 使用串行同步队列与并发队列(异步派发)(栅栏块)结合,而且不会阻塞执行异步派发的线程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 住你街区的某个不起眼的温和的邻居,可能就是你的上帝,你所在街区人们的命运即将全部改写。这些,你信吗? 一 故事发生...
    菩拉阅读 727评论 0 1
  • 本组竞品分析作业总结: 1、整体的思路没有统一,如分析的方向、思路是如何、竞品是如何; 2、基于第一点,每个分工的...
    粟漫漫阅读 921评论 0 50
  • 很多时候我们都觉得我是为了你好,就开始对别人的生活指手画脚,你应该怎么怎么样!放下自己好好想想,我们真的是为了对方...
    张玲玲的阅读 295评论 0 0
  • 目录 | 上一章 一夜温存过后徐安琪的心变得柔软,但徐安琪并没有放弃想要买一套房子的想法,她始终觉得现在不买,以后...
    乐从心阅读 456评论 3 14

友情链接更多精彩内容