原子 属性 和用法
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 对象更新时才能更新。
我已经阅读了很多类似 Is an atomic property thread safe?,
如果我错了,请纠正我,这就像我正在使用我用 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 对象更新时才能更新。