① 原子性是否安全?
一个数据的线程安全,就是这块数据即使有多个线程同时读写,也不会出现数据的错乱,内存的最后状态总是可以预见的。如果是不可预见的那么就可以说这块内存是线程不安全的。这是线程安全的概念。
首先我的观点是atomic是安全的而且是绝对安全的。
如果您认为是不安全的。其实这里边存在着一个误解。
首先atomic可能用来修饰的是什么?
一种是基本数据类型。
基本数据类型就不说了,内存太小了,除了double类型,其他的无论在何种极端操作的情况都不会导致错乱。 绝大部分情况下,多线程操作一个double和long 类型的数据,问题是不大的
另一种是一个类似NSArray * array的这个东西。
后者,一个多线程操作这个数据,会有两个层级的并发问题。
1.指针本身;2、指针所指向的内存。
所以我们考虑NSArray * array 中 这个array的多线程操作的时候,也要从上述两方面来考虑。
atomic修饰的实际上是@property(atomic)NSArray *array这个指针。它和这个指针所指向的内容根本就没有任何关系。所以,认为下边这个例子是对的人就存在着对atomic所修饰内容的一个误解。atomic它保证的是这个指针被有序的访问,并没说保证这个指针所指向的内容也是安全的。
例子:如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。
②原子性是怎么实现的。
原子性的实现用的自旋锁 spinLock (这是系统内部的东西,是runtime的源码部分相关内容可以点击查看 ),属性声明中的aotmic属性其实就是一个bool的判断值,用它来判断是否加锁,yes就用spinlock_t自旋锁上锁,保证线程安全。如果是NO就直接赋值
设置属性的时候
获取属性值的时候
为了保证他的读写线程安全加了@synchronized这个锁。至于为什么加的是这个锁 而不是其他的,这个我就不太清楚了,可能就是因为这个使用起来最简单吧,因为他的性能其实并不好 nslock 和 信号量都比他要好。但是代码量都比这个多。
读写线程安全意思是你读写这个指针指向的内存地址时候的线程安全
网友评论