Learning from b station is still silicon valley www.bilibili.com/video/BV1zb…
Tell me about your understanding of the keyword volatile.
Volatile is a lightweight synchronization mechanism provided by the Java Virtual Machine (Three features)
- Guaranteed visibility
- Atomicity is not guaranteed
- Order reordering is prohibited
What is the JMM
The JMM is the Java Memory Model, also known as the Java Memory Model, or JMM. The JMM itself is an abstract concept that does not actually exist. It describes a set of rules or specifications that define how variables in a program (including instance fields, static fields, and elements that make up array objects) are accessed
JMM regulations on synchronization:
- The shared variable values must be flushed back into main memory before the thread is unlocked
- Before locking, the thread must read the latest value of main memory into its own working memory
- The lock and the unlock are the same lock
Because the JVM to run the program of the entity is a thread, and every thread creation when the JVM to create a working memory (called the stack space) in some places, the working memory is the private data area each thread, while the Java memory model that all variables are stored in main memory, main memory is Shared memory region, all threads can access, But the thread to the operation of the variable (reading assignment, etc.) must be conducted in the working memory, the first thing to copy the variables from the main memory to their working memory space, and operation, the variable operation to complete before you write variables will be the main memory, cannot be directly operating variables in main memory, working memory storage in various threads of variables in the main memory copy copy, Therefore, different threads cannot access each other’s working memory, and communication (value passing) between threads must be completed through main memory. The brief access process is as follows:
Data transfer rate: hard disk < memory < cache < CPU
Two concepts were mentioned above: main memory and working memory
-
Main memory: The memory of the computer, which is often mentioned as 8GB, 16GB memory
-
Working memory: But we instantiate new Student, so age = 25 is also stored in main memory
- When three threads access the age variable in student at the same time, each thread makes a copy to its own working memory, thus achieving the copy of the variable
That is: visibility of the JMM memory model, which means that when a value in the main memory region is written to change by one thread, other threads immediately know the changed value and retrieve the changed value.
Cache consistency
Why is it that when a value is changed in the main thread, other threads immediately know about it? In fact, bus sniffing is used here
Before we talk about sniffing, let’s talk about cache consistency. When multiple processor tasks are involved in the same main memory area, they may have different cache data.
In order to solve the problem of cache consistency, each processor needs to follow some protocols when accessing the cache and operate according to the protocols when reading and writing, such protocols mainly include MSI, MESI and so on.
MESI
When the CPU to write information, if found operating variables are Shared variables, namely in other CPU is a copy of the variable, will inform other CPU will signal the memory cache line is set to null and void, so when the other when the CPU reads the variable, found himself cache the variable cache line is invalid, then it will be read from memory.
Bus sniffer
So how do you find out if the data is invalid?
Sniffer technology is used in the bus here, is that each processor by sniffing the spread of the data on the bus to check whether their cache value is out of date, when the processor found its own cache line corresponds to the memory address has been changed, and will set the current processor cache line to invalid state, when the processor to modify the data operation, The data is read back from memory into the processor cache.
Bus storm
What are the disadvantages of bus sniffing?
Due to Volatile’s MESI cache conformance protocol, which requires constant sniffing from main memory and CAS loops, invalid interactions can cause bus bandwidth to peak. So don’t use the volatile keyword too much. When to use volatile, when to use locks, and Syschonized are scenario-specific.
The characteristics of the JMM
Of the JMM’s three characteristics, volatile guarantees only two, visibility and order, not atomicity
- visibility
- atomic
- order
Visibility code validation
However, when we do not add any decorations to member variables, we are not aware of other threads’ modified values
package com.company;
import java.util.concurrent.TimeUnit;
/** * Assume main physical memory */
class MyData {
int number = 0;
public void addTo60(a) {
this.number = 60; }}/** * Verify the visibility of volatile * 1. Assume int number = 0, and the number variable is not prefixed with the volatile keyword */
public class VolatileDemo {
public static void main(String args[]) {
/ / resource class
MyData myData = new MyData();
// The AAA thread implements a lambda expression for the Runnable interface
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t come in");
// The thread sleeps for 3 seconds, assuming it is performing an operation
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Modify the value of number
myData.addTo60();
// Output the modified value
System.out.println(Thread.currentThread().getName() + "\t update number value:" + myData.number);
}, "AAA").start();
while (myData.number == 0) {
// The main thread waits until the number value is different from zero
}
// It is not possible to print this value because the main thread is running with a value of 0, so it is always looping
The AAA thread slept for 3 seconds, then updated the number value, which was rewritten to main memory, and was sensed by main
System.out.println(Thread.currentThread().getName() + "\t mission is over");
/** * * AAA come in * AAA update number value:60 * mission is over}}Copy the code
The output isIn the end, the thread did not stop, and the parallel did not output mission is over
When we modify a member variable in class MyData, we add the volatile keyword
/** * Assume main physical memory */
class MyData {
/** * Volatile is used to increase visibility between the main thread and other threads. If one thread changes a value in memory, other threads can immediately perceive it
volatile int number = 0;
public void addTo60(a) {
this.number = 60; }}Copy the code
The main thread has also finished executing, indicating that volatile variables have the JVM’s lightweight synchronization mechanism to be aware of modified values from other threads.