Many friends may have heard of the keyword volatile and may have used it. Prior to Java 5, it was a controversial keyword, as using it in programs often resulted in unexpected results. Only after Java 5 did the volatile keyword regain its vitality.
The function of the volatile keyword is to make all threads in the system share visible to the variables modified by the keyword, and can prohibit the thread's working memory from cached variables modified by the volatile.
volatile 2 usage scenarios:
1. Visibility: Java provides volatile keywords to ensure visibility.
When a shared variable is modified by volatile, it ensures that the modified value will be updated to main memory immediately, and when other threads need to read it, it will read the new value in memory.
However, ordinary shared variables cannot guarantee visibility, because it is uncertain when the normal shared variable is written to the main memory after it is modified. When other threads read it, the original old value may still be in the memory, so visibility cannot be guaranteed.
In addition, synchronized and Lock can also ensure visibility. Synchronized and Lock can ensure that only one thread acquires the lock at the same time and executes the synchronization code. Before releasing the lock, the modification of the variable will be refreshed to the main memory. Therefore, visibility can be guaranteed.
Let’s look at a piece of code first. If thread 1 is executed first and thread 2 is executed later:
//Thread 1boolean stop = false; while(!stop){doSomething();}//Thread 2stop = true;This code is a very typical piece of code, and many people may use this markup method when interrupting threads. But in fact, will this code run completely correctly? Will the thread be interrupted? Not necessarily. Perhaps most of the time, this code can interrupt threads, but it may also cause the thread to not be interrupted (although this possibility is very small, once this happens, it will cause a dead loop).
Let's explain why this code may cause the thread to fail to interrupt. As explained earlier, each thread has its own working memory during operation, so when thread 1 is running, it will copy the value of the stop variable and put it in its own working memory.
Then when Thread 2 changes the value of the stop variable, but has not had time to write it to the main memory, Thread 2 goes to do other things, then Thread 1 does not know about Thread 2's changes to the stop variable, so it will continue to loop.
But after modifying with volatile it becomes different:
First: Using the volatile keyword will force the modified value to be written to the main memory immediately;
Second: If you use the volatile keyword, when thread 2 modifies it, the cache line of the cache variable stop in thread 1's working memory will be invalid (if it is reflected in the hardware layer, the corresponding cache line in the L1 or L2 cache of the CPU is invalid);
Third: Since the cache line of the cache variable stop in thread 1's working memory is invalid, thread 1 will read it in main memory when it reads the value of the variable stop again.
Then when thread 2 modifies the stop value (of course, there are 2 operations here, modifying the value in thread 2's working memory, and then writing the modified value to memory), the cache line of the cache variable stop in thread 1's working memory will be invalid. When thread 1 reads, it finds that its cache line is invalid. It will wait for the corresponding main memory address of the cache line to be updated, and then read the latest value in the corresponding main memory.
Then what thread 1 reads is the latest correct value.
2. Ensure orderliness
volatile boolean initiated = false;//Thread 1:context = loadContext(); initiated = true; //Thread 2:while(!inited ){sleep()}doSomethingwithconfig(context);Make sure the context has been initialized.
3.double check
class Singleton{private volatile static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if(instance==null) {synchronized (Singleton.class) {if(instance==null)instance = new Singleton();}}return instance;}}The above is a detailed explanation of the role and usage of the volatile keyword in Java introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!