开发者

A quote from "Java Threads" book about volatile keyword

I was just wondering if someone could explain the meani开发者_运维问答ng 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.


volatile variable only ensures visibility . 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. 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.


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).


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜