原子 属性 和用法

Atomic property and usage

我已经阅读了很多类似 Is an atomic property thread safe?, or Atomic properties vs thread-safe in Objective-C 的 Whosebug 答案,但我对此有疑问:

如果我错了,请纠正我,这就像我正在使用我用 Atomic 属性 声明的计数变量,目前它的值为 5 它由两个线程访问,第一个线程将计数值增加 2,第二个线程将计数值减少 1,根据我的理解,这是按顺序进行的,就像第一个线程增加其值时一样,现在是 5 + 2 = 7;之后只有第二个线程可以访问计数变量并且只能将其值减少 1,即 7 - 1 = 6?

好的,线程可能不会按顺序执行,创建的第一个线程可能 运行 在第二个线程之后。如果线程按照您描述的顺序执行,则上述行为没有问题。但是我认为你对线程安全有一个误解。

我鼓励您阅读更多有关 Concurrency Programming Guide and Thread safe 的内容。

First thread that is increasing count value by 2

那不是原子操作,atomic 对您没有任何帮助。这是(至少)三个独立的原子操作:

  • 读取值
  • 增加值
  • 写入值

这是经典的多写入器竞争条件。另一个线程可能在 "read value" 和 "write value." 之间读取 在您的示例中,最终结果可能是 4,这样增加操作就完全丢失了(A 读取 5,B 读取 5,A +2,A 写入 7 , B -1, B写4).

atomic 旨在解决的问题是 "read value" 和 "write value" 在许多特定于平台的情况下甚至都不是原子操作。以上实际上可能是5个操作如:

  • 读低字
  • 读上位字
  • 增加值
  • 写下字
  • 写上位字

如果没有 atomic,另一个线程可能会在 "write lower word" 和 "write upper word" 之间读取并获得一个从未写入的垃圾值(一个值的一半和另一个值的一半)。通过使用 atomic,您可以确保读者将始终收到 "legitimate" 值(在某个时刻写入的值)。但这并不是一个很大的承诺。

但是正如您提供的问题中所指出的那样,如果您需要使读取和写入成为原子,您几乎肯定需要更多,因为您还希望使 "increase the value" 成为原子。所以在实践中 atomic 很少有用。如果你不需要它,它会很慢。如果你确实需要它,它可能是不够的。

基于原子的 属性,其中两个线程正在访问同一个对象以增加或减少一个值,您可以理解为两者都访问了 same/whole 值 5 但第一个线程尝试更新这个值然后被锁定,没有其他线程可以同时更新这个但是第二个线程也有相同的值 5 并且只有当第一个线程退出 Count 对象更新时才能更新。