简体   繁体   English

“Java Threads”一书中关于 volatile 关键字的引用

[英]A quote from “Java Threads” book about volatile keyword

I was just wondering if someone could explain the meaning of this:我只是想知道是否有人可以解释这个的含义:

Operations like increment and decrement (eg ++ and -- ) can't be used on a volatile variable because these operations are syntactic sugar for a load, change and a store.像递增和递减这样的操作(例如++-- )不能用于 volatile 变量,因为这些操作是加载、更改和存储的语法糖。

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.我认为递增和递减对于 volatile 变量应该可以正常工作,唯一的区别是每次读取或写入时,您将从主 memory 访问/写入主 memory 而不是从缓存。

volatile variable only ensures visibility . volatile变量确保可见性 It does not ensure atomicity .它不保证原子性 I guess, that is how the statement should be interpreted.我想,这就是该声明应该被解释的方式。

I think you're taking the quote out of context.我认为您将引用断章取义。

Of course ++ and -- can be applied to volatile variables.当然++--可以应用于 volatile 变量。 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.而且由于volatile通常意味着必须以原子方式处理它们,这与目标背道而驰。

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.执行a = a + 1使其(在某种程度上)明确表明它不是原子操作,但人们可能(错误地)认为a++是原子的。

The Java Language Specification does not have atomic operations for the ++ and -- operators. Java 语言规范没有++--运算符的原子操作。 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): Java 编译器实际上发出类似于以下步骤集的代码(实际指令将根据变量的性质而有所不同):

  1. Load the operand onto the stack using one of the operations for load ing data.使用用于load数据的操作之一将操作数加载到堆栈上。
  2. Duplicate the value of the operand on the stack (for the purpose of returning later).将操作数的值复制到堆栈上(为了稍后返回)。 This usually accomplished using a dup operation.这通常使用dup操作来完成。
  3. Increment the value on the stack.增加堆栈上的值。 Usually accomplished using the iadd operation in the VM.通常使用 VM 中的iadd操作来完成。
  4. Return the value (obtained in step 2).返回值(在步骤 2 中获得)。

As you can observe, there are multiple operations in the VM for what is commonly thought to be an atomic operation.如您所见,VM 中有多个操作通常被认为是原子操作。 The VM can ensure atomicity only upto the level of an individual operation. VM 可以确保原子性仅达到单个操作的级别。 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;使用volatile关键字,允许其他线程获取变量的最新值; 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.例如,如果变量a在前面的例子中是 volatile 的,那么读取a的值的线程如果在指令 2 和指令 3 之后读取a会看到不同的值。使用volatile并不能防止这种情况设想。 It protects against the scenario where multiple threads see multiple values for a after instruction 2 (for instance).它可以防止多个线程在指令 2 之后看到多个值a情况(例如)。

Volatile does not garanty atomicity in an opeartion that involves multiple steps. Volatile 不保证涉及多个步骤的操作中的原子性。

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.这是一个步骤,因此在这里使用 volatile 就可以了。 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.但是,如果我正在读取该值并在回写之前更改该值,则这是一个多步骤操作,并且对于此 volatile 无法管理原子性。

The increment and decrement opeartions are multi-stepped and hence the use of the volatile modifier is not sufficient.递增和递减操作是多步的,因此使用 volatile 修饰符是不够的。

Nope -- you use "volatile" to indicate that the variable can be changed by an external entity.不——您使用“volatile”来表示变量可以由外部实体更改。 This would typically be some JNI C code, or, a special register linked to some hardware such as a thermometer.这通常是一些 JNI C 代码,或者是链接到某些硬件(例如温度计)的特殊寄存器。 Java cannot guarantee that all JVMs on all architectures can will be capable of incrementing these values in a single machine cycle. Java 不能保证所有架构上的所有 JVM 都能够在单个机器周期内递增这些值。 So it doesnt let you do it anywhere.所以它不允许你在任何地方做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM