当前位置:网站首页>Volatile~ variables are not visible under multithreading

Volatile~ variables are not visible under multithreading

2022-06-23 15:04:00 It midsummer fruit

Catalog

1 summary

2 Case study

3 JMM Memory model

4 How to solve

4.1 Lock

4.2 volatile keyword


1 summary

         Under multithreading concurrent execution , Multiple threads modify shared member variables , A thread changes the value of the shared variable , Another thread cannot directly see the latest value modified by this thread .

2 Case study

Code example :

public class VisibilityDemo01 {

    public static void main(String[] args) {

        //1.  Opens a child thread 
        MyThread myThread = new MyThread();
        myThread.start();

        //2.  Main thread execution 
        while (true) {
            if (myThread.isFlag()){
                System.out.println(" The main thread enters the loop to execute ");
            }
        }

    }
}

class MyThread extends Thread{
    // Member variables 
    private  boolean flag = false;

    @Override
    public void run() {
        // Simulating business code takes time 
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        System.out.println("flag="+flag);
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

Running results :

so , When a child thread modifies the value of a variable , The main thread still does not read the modified value .

3 JMM Memory model

JMM(Java Memory Model):java Memory model , yes java A memory model defined in the virtual machine specification ,java The memory model is standardized , It's blocking the differences between different computers at the bottom .

java The memory model describes java Various variables in the program ( Thread sharing ) Access rules for , And in jvm The underlying details of storing and reading variables from memory .

JMM There are the following rules :

  • All shared variables are stored in main memory . Variables here refer to instance variables and class variables . Does not contain local variables , Because local variables are thread private , So there's no competition .
  • Each thread also has its own working memory , Thread's working memory , Keeps a working copy of the variables used by the thread
  • All operations of a thread on a variable ( read 、 take ) Must be done in working memory , Variables in main memory cannot be read or written directly
  • Different threads can not directly access the variables in the working memory of each other , The transfer of variable values between threads needs to be completed through main memory transfer .

The relationship between local memory and main memory :

Problem analysis :

Because member variables are defined in classes , So its variable values are stored in main memory ,

1) The sub thread reads data from the main memory and puts it into its corresponding working memory

2) take flag Is changed to true , But it has not been written to the main memory at this time

3) here main Method reads flag The value of is false( This is the reason why the simulated business code sleeps for one second , Otherwise, the sub thread speed is too fast, and the value is written back to the main memory as soon as it is modified , that main The value read by the thread is the latest value )

4) When a child thread t take flag When you write it back , however main Function while(true) Call is the system to compare the underlying code , Fast , It is too fast to read the value in main memory .

therefore while(true) The value of reading materials has always been false.( If there is a moment main Thread read from main memory to main memory flag The latest value of , that if Statements can be executed ,main When the thread reads the latest value from main memory , We can't control )

Causes of visibility problems : All shared variables are stored in main memory , Each thread has its own local memory , Moreover, the read and write shared data of the thread is also exchanged through the local memory , This leads to visibility problems .

4 How to solve

Now that you know the cause of the visibility problem , So how to solve it ?

4.1 Lock

Change the code in the above main thread to the following :

        //2.  Main thread execution 
        while (true) {
            synchronized (myThread){
                if (myThread.isFlag()){
                    System.out.println(" The main thread enters the loop to execute ");
                }
            }

        }

Running results :

It is found that the modified value of the child thread can be read .

reason :

1) Thread acquire lock

2) Clear working memory

3) Copy the latest value of the shared variable from the main memory to the working memory as a copy

4) Execute code

5) Refresh the value of the modified copy back to main memory

6) Thread release lock

4.2 volatile keyword

Modify part of the code in the sub thread as follows :

    // Member variables 
    private volatile boolean flag = false;

 1) Sub thread t Read data from the main memory into its corresponding working memory

2) take flag Value changed to true, But at this point flag The value has not been written back to main memory

3) here main Method reads flag The value of is false

4) When a child thread will flag When you write it back , Disable other thread copies of this variable (volatile The role of )

5) Again flag During operation, the thread will read the most values from the main memory , Put it in working memory .

summary :volatile Ensure the visibility of different threads to shared variable operations , In other words, a thread has modified volatile Decorated variable , When changes are written back to main memory , The other thread immediately sees the latest value .

 

原网站

版权声明
本文为[It midsummer fruit]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231421233783.html