我读到非原子和原子都是线程不安全的。但非原子更快,因为它允许更快的访问意味着异步和原子更慢它允许更慢的同步访问。
1 回答
Objective C 中的一个atomic
属性保证你永远不会看到部分写入。
也就是说,如果两个线程同时将值 A 和 B 写入同一个变量 X,那么对同一变量的并发读取将产生 X 的初始值,或者 A 或 B。nonatomic
不再给出这种保证。您可能会得到任何值,包括您从未明确写入该变量的值。
这样做的原因是,nonatomic
读取线程可能会读取变量,而另一个线程正在写入它。因此,您阅读的部分内容来自旧值,而另一部分来自新值。
关于它们都是线程不安全的评论是指除此之外没有提供额外保证的事实。Apple 的文档在这里给出了以下示例:
考虑一个
XYZPerson
对象,其中一个人的名字和姓氏都使用来自一个线程的原子访问器进行了更改。如果另一个线程同时访问这两个名称,原子 getter 方法将返回完整的字符串(不会崩溃),但不能保证这些值将是相对于彼此的正确名称。如果在更改之前访问了名字,但在更改之后访问了姓氏,那么您最终会得到一对不一致、不匹配的名称。
纯粹主义者可能会争辩说,这种线程安全的定义过于严格。从技术上讲,atomic
已经处理了数据竞争和排序,从语言设计者的角度来看,这就是您所需要的。
另一方面,从应用程序逻辑的角度来看,前面提到的名字-姓氏示例显然构成了一个错误。需要额外的同步来消除不希望的行为。在这个特定于应用程序的视图中,该类XYZPerson
不是线程安全的。但是在这里,我们谈论的是与语言设计者所拥有的线程安全级别不同的线程安全级别。