什么操作是原子操作

6

我有点困惑...

是否真的如此,从多个线程读写除long和double之外的所有内容都是原子操作,只需要在long和double上使用volatile?


1
你有这个的来源吗? - calebds
4个回答

8
似乎你在提到 JLS 的这个部分。对于所有原始类型(除了doublelong),保证所有线程将看到实际写入该变量的某个值。 (对于doublelong,根据JLS中的规定,第一个四字节可能由一个线程写入,最后四个字节由另一个线程写入。)但是除非将变量标记为volatile,否则它们不一定会同时看到相同的值。
即使使用volatilex += 3也不是原子性的,因为它是x = x + 3,这会进行读取和写入操作,在读取和写入之间可能会有对x的写入。这就是为什么我们需要像java.util.concurrent中的AtomicInteger和其他工具一样的东西。

3
不要混淆原子性和线程安全。长整型和双精度浮点数的写入在底层上并不是原子性的,因为每个写入都是两个独立的32位存储器。存储和加载非长整型/双精度浮点数字段是完全原子性的,假设它们不是复合写入(例如i ++)。通过原子性,我指的是您不会读取一些乱码对象,因为许多线程将不同的对象写入同一字段。出自Java Concurrency In Practice 3.1.2

从薄空安全:当一个线程没有同步地读取变量时,它可能会看到过期的值,但至少它看到的是实际由某个线程放置在那里的值,而不是某个随机值。对于所有变量,这是正确的,除了64位长整型和双精度浮点数,它们不是易失性的。JVM允许将64位读取或写入视为两个单独的32位操作,这些操作不是原子性的。


0

听起来不太对。

原子操作是一种强制所有线程等待访问资源,直到另一个线程完成它的操作。我不明白为什么其他数据类型不会是原子的,而有些却不是。


0

volatile关键字除了原子性写入值之外还有其他语义

它意味着其他线程可以立即看到更新后的值(并且它不能被优化掉)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接