Resolve the volatile keyword in Java

  • 2020-04-01 04:35:46
  • OfStack

Volatile is often used in Java multithreaded programming, and sometimes this keyword is often confused with synchronized or lock, The specific analytical As follows:
In a multi-threaded environment, there are member variable visibility problems: Java each thread is a thread stack memory space, and save the memory space for this thread runtime variable information, during a visit to a certain variable values when a thread is first according to the address of the variable to find the object heap memory or stack storage (native data types) of the specific content, and then put the assignment with a copy in this thread thread stack, followed by the variable of all operations in a thread to complete exit before and stack variable content is no relationship, in the memory copy operation is in their thread stack. When the operation is completed, the result of the operation is written back to main memory. Suppose there are two threads A and B, and the colleague operates on A variable x; A adds 1 to x, so B gets either x plus 1, or x; The volatile keyword is used to ensure that the most recent data variables in memory are retrieved, so that each time you operate on x, you check that the values of the variables in the thread stack are the same as the values of the variables in memory, and if they are different, they are reloaded.
Eg:


public class ThreadSee { 
//The t1 thread does the corresponding operation based on the flag's value, and the main thread changes 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 loads it into the corresponding thread stack and retrieves the latest data in memory for each operation
  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 you remove volatile, the code will continue to loop indefinitely.
But volatile does not 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); 
  } 
} 

According to the above code, the execution result is not expected to be 20000000,
Because with volatile variables, the JVM virtual machine simply ensures that the values loaded from main memory into thread working memory are up to date.
For example, if thread 1 and thread 2 find that the value of count in the main memory is 5 in the operation of thread stack and main memory read and load, 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 performed read and load operation, it will also update the variable value of main memory count to be 6 after operation.
Even after the two threads have been modified with the volatile keyword in a timely manner, there will still be concurrency.
In summary:
volatile This only ensures that the thread does an action to check whether the value of the current thread stack is the same as the value of the data in main memory. And lock or synchronized The method is guaranteed to be thread-safe by ensuring that only a single thread enters at any given time.
So it doesn't really make sense for multiple threads to modify a volatile variable. This is useful if one thread modifies the value of a variable that other threads are dependent on.

The above is the entire content of this article, I hope to help you with your study.


Related articles: