Detailed explanation of Java volatile keyword

Detailed explanation of Java volatile keyword

Semantics of the volatile keyword:

1. Variables defined as volatile maintain immediate visibility to all threads, but it does not mean that operations on variables modified by the volatile keyword are thread-safe under concurrency.

2. volatile variables will disable instruction rearrangement optimization

 

A note on the first point;

Volatile variables can maintain immediate visibility to all threads. The implementation of this half-sentence is based on two points: 1. Write operations of volatile variables are always synchronized to main memory immediately, and 2. Volatile variables are always immediately removed from main memory before use. refreshed in. The description of main memory refers to the Java threading model.

Regarding the second half of the first point, " volatile variables are not safe under concurrent read and write ", even if volatile variables always get the latest value from main memory immediately before use, read is not safe for virtual machines. It ensures that the atomic operation is not atomic in the underlying machine code implementation, that is to say, the value of the volatile variable in the main memory may still change during the read process, which causes the read operation to get an expired value of .

A note on the second point:

An example is needed.

package ryo;

public class Test {
	
	private int flag = 0;
	private int[] arr;
	
	public static void main(String[] args) {		
		new Test().twoThread();		
	}
	
	public void twoThread() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(flag != 1) {
				}
				System.out.println(arr[4]);
			}		
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				arr = new int[5];
				flag = 1;
			}
		}).start();
	}

}


In the above code, possibly due to the underlying instruction rearrangement optimization, the int flag = 1 in the second thread occurs before the array is initialized, which causes the first thread System.out.println(arr[4 ])Throw an exception.

Although this problem is unlikely to occur in practice, even if int flag = 1 occurs before array initialization, before thread one executes the print statement, thread two almost completes the work of array initialization, but theoretically it is possible that an error of.

At this time, you need to use volatile to disable the rearrangement function.

Adding the volatile keyword to the int flag will ensure that the int flag = 1 will be executed after the initialization statement, and the problem will be solved.

When I wrote this, I suddenly thought of a problem. There is an established rule in the Java memory model, called the program order rule, which stipulates that the operation written in the front in the same thread occurs first in the operation written in the back. Isn't that the same as the instruction? Are permutation optimization contradicting?

According to this rule, doesn't the array initialization of thread two in the above example necessarily happen before flag = 1 ?

After repeatedly flipping through the book several times and looking for related problems on the Internet, the explanation for this problem should be as follows:

The program order rule only ensures that the result of the same method remains unchanged, that is to say, the code with logical relationship has a strict sequence, and the code without logical relationship can be rearranged and optimized.

For example:

    public void test() {
       String str1 = "abc";
       String str2 = str1 + "def";
   }

For these two lines of code, it is impossible for the second line to be reordered and optimized to be executed before the first line, because they have a sequential logical relationship, which is also guaranteed by the program order rules.

And if changed to this:

    public void test() {
       String str1 = "abc";
       String str2 = "def";
   }

The initialization of str2 may be placed before str1 .

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324481056&siteId=291194637