Volatile variables
In other words, if a volatile variable is updated such that, under the hood, the value is read, modified, and then assigned a new value, the result will be a non-thread-safe operation performed between two synchronous operations. You can then decide whether to use synchronization or rely on the JRE's support for automatically synchronizing volatile variables. The better approach depends on your use case: If the assigned value of the volatile variable depends on its current value (such as during an increment operation), then you must use synchronization if you want that operation to be thread safe.
To fully understand what the
volatile
keyword does, it's first helpful to understand how threads treat non-volatile variables.
In order to enhance performance, the Java language specification permits the JRE to maintain a local copy of a variable in each thread that references it. You could consider these "thread-local" copies of variables to be similar to a cache, helping the thread avoid checking main memory each time it needs to access the variable's value.
But consider what happens in the following scenario: two threads start and the first reads variable A as 5 and the second reads variable A as 10. If variable A has changed from 5 to 10, then the first thread will not be aware of the change, so it will have the wrong value for A. If variable A were marked as being
volatile
, however, then any time a thread read the value of A, it would refer back to the master copy of A and read its current value.
If the variables in your applications are not going to change, then a thread-local cache makes sense. Otherwise, it's very helpful to know what the
volatile
keyword can do for you.
Volatile versus synchronized:
If a variable is declared as
volatile
, it means that it is expected to be modified by multiple threads. Naturally, you would expect the JRE to impose some form of synchronization for volatile variables. As luck would have it, the JRE does implicitly provide synchronization when accessing volatile variables, but with one very big caveat: reading a volatile variable is synchronized and writing to a volatile variable is synchronized, but non-atomic operations are not.
What this means is that the following code is not thread safe:
1
| myVolatileVar++; |
The previous statement could also be written as follows:
1
2
3
4
5
6
7
8
9
10
| int temp = 0; synchronize( myVolatileVar ) { temp = myVolatileVar; } temp++; synchronize( myVolatileVar ) { myVolatileVar = temp; } |
No comments:
Post a Comment