Detailed explanation of volatile keyword in Java concurrency tutorial
introduction
When it comes to multithreading, I think the most important thing is to understand the concept of a critical region.
for instance, There are 1 girl (critical area) and 49 boys (threads) in a class. The goal of boys is this girl, which will have a competitive relationship (thread safety problem). It can be extended to practical scenarios, such as adding or subtracting a number, because there is only one operation object, thread safety problems will occur in a multithreaded environment. We can have a good awareness of multithreading problems by understanding the concept of critical zone.
Jav memory model (JMM)
When it comes to multithreading, you should understand the abstract diagram of Java Memory Model (JMM). The following figure:
When thread a and thread B execute, Will read shared variables (critical area), and then copy each copy back to its own local memory to perform subsequent operations. JMM model is a specification, just like the java interface. JMM involves three issues: atomicity, visibility and ordering. The so-called atomicity. That is, whether the execution of a thread will be affected by other threads. It is non interruptible. For example:
int i=1
This statement is atomic in JMM. Whether one thread or multiple threads execute this statement, the read I is equal to 1. What is non atomicity? If java code is atomicity, there should be no thread problem. In fact, JMM stipulates that some statements are atomic. Take a non atomic example:
i ++;
This operation is not atomic. Because it contains three operations: first, read the value of I, second, add 1 to I, and third, assign the result back to I and update the value of I. Visibility. Visibility means that if a value is modified in thread a, thread B will immediately know the result.
The so-called order. The so-called order value is semantic order. That is, the code order may change. Because there is an instruction rearrangement mechanism. The so-called instruction rearrangement changes the code execution order in order to make the CPU more efficient. In order to prevent reordering errors, JMM has a happen before rule, which limits the execution of those statements before and after.
Happen-before:
Program order principle: ensure semantic seriality in a thread
Volatile principle: writing of volatile variables occurs before reading
Lock rule: Lock first and then unlock
Transitivity: if a precedes B and B precedes C, then a must precede C
The thread's start method precedes each of its operations
All operations of a thread precede the termination of the thread
The constructor of the object executes and ends before the finalize () method.
volatile
To get to the point, volatile can ensure the visibility and order of variables (Critical Zone), but it can not guarantee atomicity. For example:
public class VolatileTest implements Runnable{ private static VolatileTest volatileTest = new Volatiletest(); private static volatile int i= 0; public static void main(String[] args) throws InterruptedException { for (int j = 0; j < 20; j++) { Thread a = new Thread(new Volatiletest()); Thread b = new Thread(new Volatiletest()); a.start();b.start(); a.join();b.join(); System.out.print(i+"&&"); } } @Override public void run() { for (int j = 0; j < 1000; j++) { i++; } } } // 输出结果 // 2000&&4000&&5852&&7852&&9852&&11852&&13655&&15655&&17655&&19655&&21306 //&&22566&&24566&&26189&&28189&&30189&&32189&&34189&&36189&&38089&&
The result shows that there is a problem. Although the volatile keyword has been added to I + +, it indicates that the volatile keyword cannot guarantee the atomicity of I + +.
What scenario is suitable for using volatile keyword
1. Lightweight "read write lock" strategy
private volatile int value; public int getValue(){ return value;} public synchronized void doubleValue(){ value = value*value; }
2. Singleton mode (double check lock mechanism)
private volatile static Singleton instace; public static Singleton getInstance(){ // 没有使用同步方法,而是同步方法块 //第一次null检查 ,利用volatile的线程间可见性,不需要加锁,性能提高 if(instance == null){ synchronized(Singleton.class) { //锁住类对象,阻塞其他线程 //第二次null检查,以保证不会创建重复的实例 if(instance == null){ instance = new Singleton(); // 禁止重排序 } } } return instance;
reference resources
Modern operating system (Third Edition) Chinese version
Practical Java high concurrency programming
The art of Java Concurrent Programming
summary
The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. Thank you for your support.