[英]What operations are atomic operations
我有点困惑......
从long和double除了long和double之外的几个线程读取\\写入是真的,并且只需要使用volatile和long和double吗?
这听起来像是指JLS的这一部分 。 保证所有原始类型 - 除了double
和long
- 所有线程都会看到实际写入该变量的某些值。 (使用double
和long
,前四个字节可能由一个线程写入,最后四个字节由另一个线程写入,如JLS的该部分所述。)但它们不一定会在同一个值上看到相同的值时间,除非变量标记为volatile
。
即使使用volatile
, x += 3
也不是原子的,因为它是x = x + 3
,它执行读取和写入,并且可能在读取和写入之间写入x
。 这就是为什么我们有像AtomicInteger
这样的东西和java.util.concurrent
的其他工具。
让我们不要将原子与线程安全混淆。 长写和双写不是原子的,因为每个都是两个独立的32位存储。 存储和加载非长/双字段是完全原子的,假设它们不是复合写入(例如i++
)。
原子意味着你不会读取一些乱码对象,因为许多线程将不同的对象写入同一个字段。
来自Java Concurrency In Practice 3.1.2
超薄安全性:当一个线程在没有同步的情况下读取变量时,它可能会看到一个陈旧的值,但至少它会看到某个线程实际放置的值而不是某个随机值。 对于所有变量都是如此,除了64位long和double,它们不是volatile。 允许JVM将64位读取或写入视为两个非原子的单独32位操作。
这听起来不对。
原子操作是强制所有线程等待访问资源直到另一个线程完成它的操作。 我不明白为什么其他数据类型是原子的,而其他数据类型则不是。
volatile除了原子地写入值之外还有其他语义
这意味着其他线程可以立即看到更新的值(并且无法优化)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.