In Java multi-threaded programming, volatile is often found. Sometimes this keyword is often confused with synchronized or lock. The specific analysis is as follows:
In a multi-threaded environment, there will be a problem of visibility of member variables: Each thread in java has a memory space of a thread stack, which saves the variable information of the thread when it is running. When a thread accesses a certain variable value, it will first find the object's heap memory or the specific content of the stack (native data type) based on the address of the variable, and then save the same value copy in the thread stack of this thread. Then, all operations on this variable have nothing to do with the variable content in the stack before the thread exits. It operates on the copy in the thread stack. After the operation is completed, the result of the operation will be written back to the main memory. If there are two threads A and B, and colleagues operate a certain variable x; A adds 1 to x, then the copy obtained by B may be the result of x plus 1, or x; to ensure that the latest data variable in memory is needed to add the volatile keyword, so every time you operate on x, you will check whether the value of the variable in the thread stack is the same as the value of the variable in memory, and if it is different, it will be loaded again.
eg:
public class ThreadSee { //The t1 thread will perform corresponding operations based on the flag's value, and the main thread will change the value of t1 public static void main(String[] args) throws InterruptedException { ThReadTest th= new ThReadTest(); Thread t1 = new Thread(th); t1.start(); Thread.sleep(1000); th.changeFlag(); Thread.sleep(2000); System.out.println(th.getFlag()); } } class ThReadTest implements Runnable{ // When a thread accesses a variable, it will load it into the corresponding thread stack. Each operation, it must obtain the latest data in memory private volatile boolean stopflag; @Override public void run() { int i=0; while(!stopflag){ i++; System.out.println("=="+Thread.currentThread().getName()); } System.out.println("Thread finish:"+i); } public void changeFlag(){ this.stopflag=true; System.out.println(Thread.currentThread().getName()+"*********"); } public boolean getFlag(){ return stopflag; } } If the above code is removed, it will continue to execute in a dead loop.
But volatile cannot guarantee thread-safe synchronization
eg:
public class ThreadSave implements Runnable{ static ThreadSave sync = new ThreadSave(); static volatile int j=0; //Lock lock =new ReentrantLock(); public void inscane(){ // lock.lock(); for(int i=0;i<10000000;i++){ j++; } // lock.unlock(); } @Override public void run() { inscane(); } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(sync); Thread t2 = new Thread(sync); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(j); } } The result of execution according to the above code is not expected to be 20000000,
Because for variables modified by volatile, the jvm virtual machine only ensures that the value loaded from main memory to thread working memory is the latest.
For example, if thread 1 and thread 2 are performing thread stack and main memory read and load operations, and find that the value of count in main memory is 5, then the latest value will be loaded. After thread 1 heap count is modified, it will be written into main memory, and the count variable in main memory will become 6;
Since thread 2 has already performed read and load operations, after performing the operation, the variable value of the main memory count will also be updated to 6;
This causes concurrency to occur after two threads are modified with the volatile keyword in time.
In summary:
volatile will only ensure that the thread does an action that checks whether the variable value of the current thread stack is the same as the data value in the main memory, that's all. lock or synchronized will ensure that only a single thread enters the method at a certain moment, thereby ensuring its thread safety.
So if multiple threads modify a volatile variable, then there is no actual logical meaning. If a thread modifies the variable value of other threads that depend on modifying, it will be useful at this time.
The above is all about this article, I hope it will be helpful to everyone's learning.