We know that the operations of setting variable values in Java are atomic operations except for long and double type variables. In other words, there is no need to synchronize simple read and write operations of variable values.
Before JVM 1.2, Java's memory model implementation always read variables from main memory, which did not require special attention. With the maturity and optimization of the JVM, the use of volatile keywords has become very important in multi-threaded environments. Under the current Java memory model, threads can store variables in local memory (such as machine registers) instead of directly reading and writing in main memory. This may cause one thread to modify the value of a variable in main memory, while another thread continues to use its copy of the variable value in the register, causing data inconsistency. To solve this problem, you only need to declare the variable as volatile (unstable) as in this program. This indicates to the JVM that this variable is unstable and will be stored in main memory every time it is used. to read. Generally speaking
Therefore, in a multi-tasking environment, flags shared between tasks should be modified with volatile.
Each time a member variable modified by Volatile is accessed by a thread, the value of the member variable is forced to be reread from the shared memory. Moreover, when a member variable changes, the thread is forced to write the changed value back to the shared memory. In this way, at any time, two different threads always see the same value of a member variable.
The Java Language Specification states: For optimal speed, threads are allowed to save private copies of shared member variables and compare them with the original values of the shared member variables only when the thread enters or leaves a synchronized code block.
In this way, when multiple threads interact with an object at the same time, attention must be paid to allowing the threads to obtain changes in shared member variables in a timely manner.
The volatile keyword prompts the VM: it cannot save a private copy of this member variable, but should directly interact with the shared member variable.
Usage suggestion: Use volatile on member variables accessed by two or more threads. It is not necessary to use when the variable to be accessed is already in a synchronized code block or is a constant.
Since using volatile blocks out the necessary code optimization in the VM, it is less efficient, so this keyword must be used only when necessary.
In the implementation of the virtual machine, basic types such as int and char are one word in length. And long and double occupy two words in length. In some virtual machine implementations, the two word lengths may be treated as two atomic single word lengths.
If long and double are not modified with volatile, if multiple threads access the variable, the result will be confusing due to the overall non-atomicity of the long operation.
For example: int, one thread writes 4, and another writes 5. The final value must be 4 or 5. And the long type may be a messy value.