引用自《Java Threads》关于 volatile 关键字的书

发布于 2024-11-10 11:12:45 字数 234 浏览 6 评论 0原文

我只是想知道是否有人可以解释一下这句话的含义:

诸如增量和等操作 递减(例如 ++--)不能 用于易失性变量,因为 这些操作是语法糖 用于加载、更改和存储。

我认为增量和减量对于易失性变量来说应该可以正常工作,唯一的区别是每次读取或写入时,您都会从主内存访问/写入,而不是从缓存访问/写入。

I was just wondering if someone could explain the meaning of this:

Operations like increment and
decrement (e.g. ++ and --) can't be
used on a volatile variable because
these operations are syntactic sugar
for a load, change and a store.

I think increment and decrement should just work fine for a volatile variable, the only difference would be every time you read or write you would be accessing from/writing to main memory rather than from cache.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的往事 2024-11-17 11:12:45

易失性变量确保可见性。它不能确保原子性。我想,这句话应该这样解释。

volatile variable only ensures visibility . It does not ensure atomicity. I guess, that is how the statement should be interpreted.

ゃ懵逼小萝莉 2024-11-17 11:12:45

我认为你断章取义了这句话。

当然++--可以应用于易失性变量。它们只是不会是原子的。

由于易失性通常意味着它们必须以原子方式处理,这与目标背道而驰。

++-- 的问题在于,它们可能感觉好像它们是原子的,但实际上它们不是。

执行a = a + 1(在某种程度上)明确它不是原子操作,但人们可能(错误地)认为a++是原子的。

I think you're taking the quote out of context.

Of course ++ and -- can be applied to volatile variables. They just won't be atomic.

And since volatile often implies that they must be handled in an atomic manner, this is counter to the goal.

The problem with ++ and -- is that they might feel like they are atomic, when indeed they are not.

Doing a = a + 1 makes it (somewhat) explicit that it is not an atomic operation, but one might (wrongly) think that a++ is atomic.

以可爱出名 2024-11-17 11:12:45

Java 语言规范没有针对 ++-- 运算符的原子操作。换句话说,当您按照以下方式编写代码时:

a++;

Java 编译器实际上会发出类似于以下步骤集的代码(实际指令将根据变量的性质而有所不同):

  1. 使用以下命令将操作数加载到堆栈上 : 加载数据的操作之一。
  2. 复制堆栈上操作数的值(以便稍后返回)。这通常使用dup操作来完成。
  3. 增加堆栈上的值。通常使用 VM 中的 iadd 操作来完成。
  4. 返回值(在步骤 2 中获得)。

正如您所观察到的,VM 中存在多个通常被认为是原子操作的操作。 VM 只能确保单个操作级别的原子性。任何进一步的要求只能通过同步或其他技术来实现。

使用volatile关键字,允许其他线程获取变量的最新值;对变量的所有读取操作都将根据每条指令返回最近更新的值。例如,如果变量 a 在前面的示例中是易失性的,那么读取 a 值的线程将看到不同的值(如果它要读取 ) a 在指令 2 和指令 3 之后。使用 易失性 不能防止这种情况。它可以防止多个线程在指令 2 之后看到多个 a 值(例如)的情况。

The Java Language Specification does not have atomic operations for the ++ and -- operators. In other words, when you write code in the following manner:

a++;

the Java compiler actually emits code that is similar to the set of steps below (the actual instructions will vary depending on the nature of the variable):

  1. Load the operand onto the stack using one of the operations for loading data.
  2. Duplicate the value of the operand on the stack (for the purpose of returning later). This usually accomplished using a dup operation.
  3. Increment the value on the stack. Usually accomplished using the iadd operation in the VM.
  4. Return the value (obtained in step 2).

As you can observe, there are multiple operations in the VM for what is commonly thought to be an atomic operation. The VM can ensure atomicity only upto the level of an individual operation. Any further requirement can be achieved only via synchronization or other techniques.

Using the volatile keyword, allows other threads to obtain the most recent value of a variable; all read operations on a variable will return the recently updated value on a per-instruction basis. For example, if the variable a were to be volatile in the previous example, then a thread reading the value of a would see different values if it were to read a after instruction 2 and after instruction 3. Use of volatile does not protect against this scenario. It protects against the scenario where multiple threads see multiple values for a after instruction 2 (for instance).

公布 2024-11-17 11:12:45

易失性不保证涉及多个步骤的操作中的原子性。

这样看,我正在读取一个值,这就是所有正在做的事情,读取操作是一个原子操作。这是一个步骤,因此这里使用 volatile 就可以了。然而,如果我正在读取该值并在写回之前更改该值,则这是一个多步骤操作,并且对于此 易失性 不管理原子性。

递增和递减操作是多步的,因此仅使用 volatile 修饰符是不够的。

Volatile does not garanty atomicity in an opeartion that involves multiple steps.

Look at it this way it I am reading a value and that is all am doing, the read operation is an atomic operation. It is a single step and hence the use of volatile here will be fine. If however I am reading that value and changing that value before writing back, that is a multistep operation and for this volatile does not manage the atomicity.

The increment and decrement opeartions are multi-stepped and hence the use of the volatile modifier is not sufficient.

绅士风度i 2024-11-17 11:12:45

不——您使用“易失性”来指示该变量可以由外部实体更改。
这通常是一些 JNI C 代码,或者链接到某些硬件(例如温度计)的特殊寄存器。 Java 不能保证所有体系结构上的所有 JVM 都能够在单个机器周期内递增这些值。所以它不允许你在任何地方这样做。

Nope -- you use "volatile" to indicate that the variable can be changed by an external entity.
This would typically be some JNI C code, or, a special register linked to some hardware such as a thermometer. Java cannot guarantee that all JVMs on all architectures can will be capable of incrementing these values in a single machine cycle. So it doesnt let you do it anywhere.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文