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

作者: natewang | 来源:发表于2015-08-09 10:12 被阅读7800次

这个问题很少遇到,但是答案当然不是。
atomic在set方法里加了锁,防止了多线程一直去写这个property,造成难以预计的数值。但这也只是读写的锁定。跟线程安全其实还是差一些。看下面。

@interface MONPerson : NSObject 
@property (copy) NSString * firstName; 
@property (copy) NSString * lastName; 
- (NSString *)fullName; 
@end

Thread A:
p.firstName = @"Rob";
Thread B:
p.firstName = @"Robert";
Thread A:
label.string = p.firstName; // << uh, oh -- will be Robert

但是如果有个C也在写,D在读取,D会读到一些随机的值(ABC修改的值),这就不是线程安全的了。最好的方法是使用lock。

Thread A:
[p lock]; // << wait for it… … … …
// Thread B now cannot access 
pp.firstName = @"Rob";
NSString fullName = p.fullName;
[p unlock];
// Thread B can now access plabel.string = fullName;

Thread B:
[p lock]; // << wait for it… … … …
// Thread A now cannot access p…
[p unlock];

atomic有个很大的问题是很慢,要比nonatomic慢20倍。
当然最后建议这种数值数值变化可以让服务器来做。

相关文章

  • atomic与线程安全

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

  • 题库整理(一)

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

  • iOS 面试提(二)

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

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

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

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

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

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

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

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

    atomic在set方法里加了锁,防止了多线程一直去写这个property,造成难以预计的数值。但这也只是读写的锁...

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

    atomic不是绝对的线程安全。atomic的本意是指属性的存取方法是线程安全的,并不保证整个对象是线程安全的。 ...

  • 面试与问题记录 3

    一 .nonatomic 与atomic 区别,atomic是绝对线程安全吗 ?常用的锁有那些? 答: nonat...

  • atomic与线程安全

    atomic在日常开发中是个很少使用,也是个很容易出现错误的知识点,那么atomic能够保证线程安全吗? 答案是不...

网友评论

  • 摇滚马农:其实这题目问的有问题,atomic绝对是线程安全。
    何谓线程安全,线程安全就是在保证读写在多线程下串行执行。
    这题问的应该是为什么在多线程情况下我们不用atomic。
    因为如有三个及以上的线程访问同一资源,atomic并不能保证程序的一致性。
    因为线程安全只能保证临界区不在多线程下同时执行,但是
    三个线程还牵扯到先来后到的问题,这已经不是线程安全问题了。
    比如A读取,B,C写入,假如B先执行,而A,C到底谁先来会影响A的值的。
    所以既然无论如何都无法保证程序的一致性,那么用atomic反而会增加
    程序负担,还不如不如。对于并发问题,让程序员自己去解决。

    简而言之,就是我做的已经没问题了,但是你用的有问题我仍然无法保证,
    那么干脆别用,得不偿失。
  • 梁森的简书:atomic的不安全性体现在哪里呢?
  • 大江山岚_f450:po主理解错了。atomic是绝对安全的。
    我们知道,在64位的操作系统下,所有类型的指针,包括void * 都是占用8个字节的。超过4个字节的基本类型数据都会有线程并发的问题。
    那所有的指针类型都会有这个问题。
    以oc 下的 NSArray * 为例子,如果一个多线程操作这个数据,会有两个层级的并发问题
    1、指针本身
    2、指针所指向的内存

    指针本身也是占用内存的,并且一定是8个字节,第二部分,指针所指向的内存,这个占多少字节就不一定了,有可能非常大,有可能也就1个字节


    所以我们考虑NSArray * array 这个数据array 多线程操作的时候,必须分成两部分来描述,一个是&array这个指针本身,另一个则是它所指向的内存 array
    大家注意下 &array 和 array 的区别 ,其实不用纠结,你就想象现在有两块内存,一块是8字节,一块n字节,8字节里面放的值,就是n字节内存的首地址,

    ok 现在联系上atomic,如果用@property(atomic)NSArray *array 修饰之后,会有什么影响?网上说的很多,不再赘述,我只想从内存的角度来解释这个过程

    首先第一点,你要记住,@property(atomic)NSArray *array 其实修饰的是这个指针,也就是这个8字节内存,跟第二部分数据n字节没有任何关系,被atomic 修饰之后,你不可能随意去多线程操作这个8字节,但是对8字节里面所指向的n字节没有任何限制!这就是所有网络上所说的 atomic 不安全的真相 !!!

    我们来看一下,这能怪atomic? 本身你修饰的是一个指针,并且atomic 已经完美的履行了它的指责,你现在不可能对这个8字节进行无序的多线程操作,这就够了呀!atomic没有任何鸟问题。有问题的是人,你本身并未对n字节做任何的限制,所以把问题怪罪到atomic 上真的是很不合理
    快乐的一直小青蛙:十分的赞 好有道理
    Frued:特意登录点赞
  • Seeulater:实际情况好像也不是这样的,atomic 标记的属性 set方法里面 有一个 自旋锁,效率也是很高的,比自己加锁效率要高出很多倍(具体多少我忘记了 回头我把数据也贴过来)
    wizet:请问一下,你是从哪里看的数据啊~~~~
  • 最爱东山哥丶:atomic是读写安全的,但是一个线程里做很多事情,不止一次读或写。有可能是间隔性的读写。
  • 大号鱼骨头:但是苹果推出这个属性的原因是啥? :joy:
  • 999cc57f2e87:当使用atomic时,虽然对属性的读和写是原子性的,但是仍然可能出现线程错误:当线程A进行写操作,这时其他线程的读或者写操作会因为该操作而等待。当A线程的写操作结束后,B线程进行写操作,然后当A线程需要读操作时,却获得了在B线程中的值,这就破坏了线程安全,如果有线程C在A线程读操作前release了该属性,那么还会导致程序崩溃。所以仅仅使用atomic并不会使得线程安全,我们还要为线程添加lock来确保线程的安全。
    CNMD_LJ:A线程读的值和B线程写值并没有造成“安全”问题
    大号鱼骨头:@SarielTang 按你这么说,除非是独占资源,不然只要是共享资源总会被别的线程读和写的。
    LoyalToOrigin:@SarielTang 学到了, 谢谢详细的解释
  • 牧马:并没有解释 atomic 不一定是线程安全的问题啊????? :cry:
  • daixunry::+1: 能不能这样说,只有对操作进行lock,而不是属性的原子性,才能确保线程安全,例如,对mutableArray的多线程读写?那么属性的原子性这个解决方案是不严谨的么?

本文标题:使用atomic一定是线程安全的吗?

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