哪个是线程安全的原子或非原子?

时间:2012-09-10 07:42:38

标签: objective-c multithreading cocoa thread-safety atomic

我搜索并发现不可变是线程安全而可变不是。这可以。 但是我得到了误导性的笔记,博客,关于线程安全的原子与非原子的答案,请给出答案的解释。

假设存在一个名为“name”的原子字符串属性,如果从线程A调用[self setName:@"A"],则从线程B调用[self setName:@"B"],并从线程C调用[self name],然后不同线程上的所有操作都将按顺序执行,这意味着如果一个线程正在执行setter或getter,那么其他线程将等待。这使得属性“name”读/写安全,但如果另一个线程D同时调用[name release],则此操作可能会导致崩溃,因为此处不涉及setter / getter调用。这意味着对象是读/写安全(ATOMIC)但不是线程安全的,因为另一个线程可以同时向对象发送任何类型的消息。

如果属性“name”是非原子的,那么上面例子中的所有线程--A,B,C和D将同时执行,产生任何不可预测的结果。在原子的情况下,A,B或C中的任何一个将首先执行,但D仍然可以并行执行。

您对此的评论将有助于我们......

我的问题是,“在可可,原子或非原子中是线程安全的吗?”

5 个答案:

答案 0 :(得分:10)

atomic保证对变量的原子访问,但它确保您的代码线程安全。也不是非原子的。

使用" atomic",合成的setter / getter方法将确保始终从getter返回整个值或由setter设置,而不管任何其他线程上的setter活动。因此,如果线程A位于getter的中间,而线程B调用setter,则实际的可行值将返回给A中的调用者。对于非原子,您没有这样的保证。

答案 1 :(得分:8)

atomic使得以下线程安全。

self.myProperty = value;

id value = self.myProperty

它不会使以下线程安全

[myPorperty addObject:value];

Atomic使得设置或获取属性的线程安全,但它不会调用该属性本身的任何方法线程安全。

设置或获取值可能需要多个CPU指令,这意味着设置或获取可以中途中断,而另一个线程可以执行某些操作,使前一个线程的进度在设置中或使值无效。< / p>

atomic表示以某种方式设置或获取值,以便它发生在一条不可分割的指令中,因此没有其他线程可以介入一半并搞砸了。

不可变对象是线程安全的简单,因为你不能改变它们,因为你可以从一个不可变对象改变一个属性,这样除非你使它成为原子,否则该部分将不是安全的。

答案 2 :(得分:1)

还有一个“原子”属性没有被提及,这是ARC之前线程安全所需要的(可能仍然是)。首先解释为什么需要它:假设没有ARC,你读取一个对象属性并立即保留它。但是另一个线程可能只是在你读取属性和retain调用之间,将object属性设置为nil,导致对象被释放。您将保留发送到解除分配的对象,这是不健康的。这将是一个非常罕见的错误,因为它只会在时机恰到好处时发生。为防止这种情况,原子对象属性始终返回自动释放的对象。

答案 3 :(得分:0)

1)两者都是非线程安全的。 2)Atomic只是一个读写保险箱。 3)但是如果你想让线程安全,你需要实现一些锁定机制来进行线程,如互斥锁,自旋锁。 阅读更多 ... https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

答案 4 :(得分:-7)

非原子是线程安全的。保证获得变量的价值。