我只是想知道是否有人可以解释这个的含义:
增量和增量等操作 减量(例如
++
和--
)不能 用于volatile变量因为 这些操作都是语法糖 负载,变更和商店。
我认为增量和减量应该适用于一个易变量的变量,唯一的区别是每次你读或写时你都要从主内存访问/写入而不是从缓存中访问。
答案 0 :(得分:8)
volatile
变量仅确保visibility。它不能确保atomicity。我猜,这就是解释声明的方式。
答案 1 :(得分:7)
我认为你的报价是脱离背景的。
当然++
和--
可以应用于volatile变量。它们不会是原子的。
由于volatile
经常意味着必须以原子方式处理它们,这与目标背道而驰。
++
和--
的问题在于,他们可能感觉就像他们是原子的一样,而实际上他们不是。
执行a = a + 1
使它(某种程度上)明确表明它不是原子操作,但是一个可能(错误地)认为a++
是原子的。
答案 2 :(得分:3)
Java语言规范没有++
和--
运算符的原子操作。换句话说,当您以下列方式编写代码时:
a++;
Java编译器实际上发出的代码类似于下面的一组步骤(实际指令将根据变量的性质而变化):
load
数据的操作之一将操作数加载到堆栈中。dup
操作完成。iadd
操作完成。正如您所看到的,VM中有多个操作通常被认为是原子操作。 VM可以确保原子性仅达到单个操作的级别。任何进一步的要求只能通过同步或其他技术来实现。
使用volatile
关键字,允许其他线程获取变量的最新值;对变量的所有读取操作都将基于每个指令返回最近更新的值。例如,如果变量a
在前面的示例中是易变的,那么读取a
值的线程如果在指令2之后读取a
则会看到不同的值。在指示之后3.使用volatile
并不能防止这种情况发生。它可以防止多个线程在指令2(例如)之后看到a
的多个值的情况。
答案 3 :(得分:1)
挥发性不会在涉及多个步骤的操作中保证原子性。
以这种方式看待它我正在读取一个值而且这一切正在进行中,读取操作是一个原子操作。这是一个步骤,因此在这里使用挥发性就好了。但是,如果我正在读取该值并在写回之前更改该值,那么这是一个多步操作,并且对于此volatile不会管理原子性。
增量和减量操作是多步的,因此使用挥发性修饰剂是不够的。
答案 4 :(得分:0)
不 - 您使用“volatile”表示该变量可以由外部实体更改。 这通常是一些JNI C代码,或者是与某些硬件(如温度计)相关联的特殊寄存器。 Java无法保证所有体系结构上的所有JVM都能够在单个机器周期中递增这些值。所以它不会让你在任何地方做到这一点。