Home >Java >javaTutorial >What are the volatile and Java memory models of java high concurrency?

What are the volatile and Java memory models of java high concurrency?

PHPz
PHPzforward
2023-04-30 23:46:151574browse

public class Demo09 {	
    public static boolean flag = true;	
    public static class T1 extends Thread {	
        public T1(String name) {	
            super(name);	
        }	
        @Override	
        public void run() {	
            System.out.println("线程" + this.getName() + " in");	
            while (flag) {	
                ;	
            }	
            System.out.println("线程" + this.getName() + "停止了");	
        }	
    }	
    public static void main(String[] args) throws InterruptedException {	
        new T1("t1").start();	
        //休眠1秒	
        Thread.sleep(1000);	
        //将flag置为false	
        flag = false;	
    }	
}

Run the above code and you will find that the program cannot be terminated.

There is a loop in the run() method of thread t1. The flag is used to control whether the loop ends. The main thread sleeps for 1 second and sets the flag to false. It is said that at this time, thread t1 will detect that the flag is false, prints "Thread t1 stopped", why is the result different from what we expect? By running the above code, we can judge that the flag seen in t1 is always true. After the main thread sets the flag to false, it is not seen in the t1 thread, so it keeps looping.

So why can’t I see the flag modified by the main thread in t1?

To explain this, we need to first understand the Java Memory Model (JMM). Communication between Java threads is controlled by the Java Memory Model (referred to as JMM in this article). JMM determines how a thread writes to shared variables. When visible to another thread. From an abstract point of view, JMM defines the abstract relationship between threads and main memory: shared variables between threads are stored in main memory (main memory), and each thread has a private local memory (local memory) , a copy of the shared variable that the thread reads/writes is stored in local memory. Local memory is an abstract concept of JMM and does not really exist. It covers caches, write buffers, registers, and other hardware and compiler optimizations. The abstract schematic diagram of the Java memory model is as follows:

What are the volatile and Java memory models of java high concurrency?

As can be seen from the above figure, thread A needs to communicate with thread B and must go through the following two steps:

1. First, thread A refreshes the updated shared variables in local memory A to the main memory

2. Then, thread B goes to the main memory to read the previously updated shared variables of thread A. Shared variables

The following is a schematic diagram to illustrate these two steps:

What are the volatile and Java memory models of java high concurrency?

As shown in the figure above, local memory A and B have shared variables in main memory copy of x. Assume that initially, the x values ​​in these three memories are all 0. When thread A is executing, it temporarily stores the updated x value (assuming the value is 1) in its own local memory A. When thread A and thread B need to communicate, thread A will first refresh the modified x value in its local memory to the main memory. At this time, the x value in the main memory becomes 1. Subsequently, thread B goes to the main memory to read the updated x value of thread A. At this time, the x value of thread B's local memory also becomes 1. Overall, these two steps are essentially thread A sending messages to thread B, and this communication process must go through main memory. JMM provides Java programmers with memory visibility guarantees by controlling the interaction between main memory and each thread's local memory.

After understanding JMM, let’s look at the question at the beginning of the article. Why can’t we see the value of the flag that was modified to false by the main thread in thread t1? There are two possibilities:

1 .After the main thread modified the flag, it did not refresh it to the main memory, so t1 could not see

2. The main thread refreshed the flag to the main memory, but t1 always read the flag in its own working memory. The value does not go to the main memory to obtain the latest value of flag

For the above two situations, is there any way to solve it?

Is there such a method: after the thread modifies the copy in the working memory, it is immediately refreshed to the main memory; every time the shared variable is read in the working memory, it is Read again from main memory and then copy to working memory.

Java provides us with such a method. Using volatile to modify shared variables can achieve the above effect. Variables modified by volatile have the following characteristics:

1. In a thread When reading, each read will read the latest value of the shared variable from the main memory, and then copy it to the working memory

2. The thread modifies the copy of the variable in the working memory. After the modification, It will be flushed to the main memory immediately

Let’s modify the sample code at the beginning:

public volatile static boolean flag = true;

Use volatile to modify the flag variable, and then run the program and output:

线程t1 in	
线程t1停止了

Now the program can be stopped normally. Volatile solves the problem of visibility of shared variables in multi-threads. Visibility refers to whether the modification of shared variables by one thread is visible to another thread. \

The above is the detailed content of What are the volatile and Java memory models of java high concurrency?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete