当前位置:网站首页>Three characteristics of volatile keyword [data visibility, prohibition of instruction rearrangement and no guarantee of operation atomicity]
Three characteristics of volatile keyword [data visibility, prohibition of instruction rearrangement and no guarantee of operation atomicity]
2022-04-23 13:43:00 【0oIronhide】
volatile
volatile Two functions of keywords : Ensure visibility of shared data 、 Ensure that the instruction is rearranged ; A problem : The atomicity of data shared by multi-threaded operations is not guaranteed .
Ensure visibility of shared data
Look at the following code :
public class VolatileDemo {
boolean stop = false;
public static void main(String[] args) throws Exception {
VolatileDemo test = new VolatileDemo();
new Thread(() -> test.execute(), "Thread1").start();
Thread.sleep(1000);
new Thread(() -> test.shutdown(), "Thread2").start();
}
void execute() {
while (!stop) {
String str = "str";
}
}
void shutdown() {
System.out.println("do stop");
stop = true;
}
}
The console is printing do stop after , It's going to go into a dead cycle , That is to say
stop = true;after ,Thread1 I don't know yet stop Has changed to true 了 , therefore while The loop will run all the time ; increase volatile,volatile boolean stop = false;, There will be no dead cycle .volatile After the modified variable is changed , Other threads that use this variable can immediately know .
Then why not add volatile, Other threads don't know that the variable is changed ? This is to say JMM(Java Memory model )
JMM
JMM It describes Java Various variables in the program ( Threads share variables ) Access rules for , And in JVM Store variables in memory , The underlying details of reading variables from memory .
JMM The agreement of
- All shared variables are stored in main memory , The variables here refer to instance variables and class variables , Does not contain local variables , Because local variables are thread private , So there's no competition .
- Each thread has its own working memory , When a thread wants to read a variable in main memory , First read the variables in main memory into your working memory .
- All operations of a thread on variables ( read , take ) Must go through working memory , Cannot read or write variables directly from main memory .
- Before thread locking , The new value in main memory must be read into working memory ; Before thread unlocking , Shared variables must be flushed back to main memory immediately ; Lock and unlock with the same lock
- Variables in the working memory of other threads cannot be accessed directly between different threads , The value transfer of variables between threads needs to be completed through main memory transfer .
Eight interactive operations between thread working memory and main memory

- lock( lock ) A variable acting on main memory , Mark a variable as thread exclusive
- unlock( Unlock ) A variable acting on main memory , It releases a locked variable , Freed variables can be locked by other threads
- read ( Read ) Operates on the main memory variable , It transfers the value of a variable from main memory to the working memory of the thread , For subsequent load The action to use
- load ( load ) A variable acting on working memory , It is the read Operations put variables from main memory into working memory
- use( Use ) Variables in working memory , It transfers variables in working memory to the execution engine , Whenever the virtual machine encounters a value that needs to be used to the variable , You'll use this command
- assign( assignment ) Variables in working memory , It puts a value received from the execution engine into a variable copy of working memory
- store( Storage ) Variables acting on main memory , It transfers the value of a variable from working memory to main memory , So that the follow-up write Use
- write( write in ) Variables acting on main memory , It is the store The value of the variable obtained by the operation from working memory is put into the variable in main memory
Rules for eight operations :
- Used read must load, Used store must write
- Threads are not allowed to discard the most recent assign operation , That is, after the data in the working memory is changed , Must tell main memory
- Not allowed a thread will not have assign Data from working memory is synchronized back to main memory
- A new variable must be born in main memory , Working memory is not allowed to use an uninitialized variable directly
- Only one thread can execute a variable at the same time lock. many times lock after , Must perform the same number of times unlock
- If you do... For a variable lock operation , The value of this variable in all working memory is cleared , Before the execution engine uses this variable , Must be renewed load or assign The operation initializes the value of the variable
- If a variable is not lock, It can't be unlock operation . Also can not unlock A variable locked by another thread
- On a variable unlock Before the operation , This variable must be synchronized back to main memory
Because after the variable in main memory changes , The variables in the thread working memory did not change in time , The reason for the invisibility of variables , And added volatile after , Once the variable in main memory changes , Other threads that use this variable can immediately know , And update the variables in the working memory .
volatile Prohibit command rearrangement
Command rearrangement
To improve performance , Compilers and processors often reorder instructions in a given order of code execution .
For example, in Java When creating objects in , The following order should be followed :
1. The computer allocates memory space to variables first
2. Create an instance object
3. Point the instance object to memory
Because of the rearrangement of instructions , May appear 1>3>2 The situation of
Instruction rearrangement under multithreading will also cause some problems , Let's use the singleton pattern as an example :
public class LazySingle {
private LazySingle() {
}
private static volatile LazySingle lazySingle;
public static LazySingle getInstance() {
if (lazySingle == null) {
synchronized (LazySingle.class) {
if (lazySingle == null) {
lazySingle = new LazySingle();
/** * This is a Dual detection mode An example of a lazy man DCL Slacker type * Under multithreading, if the variable lazySingle no need volatile modification There may be problems : * * 1. The computer allocates memory space to variables first * 2. Create an instance object * 3. Point the instance object to memory * * Generally speaking, according to 1,2,3 Steps for * When an instruction rearrangement occurs , It could happen 1,3,2 The situation of * When A Thread execution to new LazySingle() when , The object has been allocated space but has not yet been instantiated * B Thread judgment lazySingle Not for null, but lazySingle Not instantiated yet , There will be problems * * So here it is lazySingle Add keywords volatile, To ensure that the computer does not rearrange instructions */
}
}
}
return lazySingle;
}
}
volatile The atomicity of data shared by multi-threaded operations is not guaranteed
Look at the following code :
public class VolatileDemo2 {
static volatile int num = 0;
static void add() {
num++;
}
public static void main(String[] args) {
//volatile The atomicity of operation data cannot be guaranteed
for (int i = 1; i <= 20; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
add();
}
}).start();
}
while (Thread.activeCount() > 2) {
Thread.yield();
}
System.out.println(num);
}
}
This code opens 20 Threads , A thread calls a pair a thousand times add Method , Logically, the final result num It should be equal to 20000, But the results are less than 20000, Make sure every time add Can be executed successfully , Method pair num++ The operation must be locked .
版权声明
本文为[0oIronhide]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230600132417.html
边栏推荐
- 集简云 x 飞书深诺,助力企业运营部实现自动化办公
- 零拷贝技术
- ACFs file system creation, expansion, reduction and other configuration steps
- The interviewer dug a hole for me: how many concurrent TCP connections can a single server have?
- ./gradlew: Permission denied
- Antd design form verification
- kettle庖丁解牛第16篇之输入组件周边讲解
- RTOS mainstream assessment
- Stack protector under armcc / GCC
- [point cloud series] neural opportunity point cloud (NOPC)
猜你喜欢

The interviewer dug a hole for me: how many concurrent TCP connections can a single server have?

Short name of common UI control

ACFs file system creation, expansion, reduction and other configuration steps

Detailed explanation of ADB shell top command

100000 college students have become ape powder. What are you waiting for?
![[official announcement] Changsha software talent training base was established!](/img/ee/0c2775efc4578a008c872022a95559.png)
[official announcement] Changsha software talent training base was established!

RTOS mainstream assessment

浅谈js正则之test方法bug篇

AI21 Labs | Standing on the Shoulders of Giant Frozen Language Models(站在巨大的冷冻语言模型的肩膀上)
![[Video] Bayesian inference in linear regression and R language prediction of workers' wage data | data sharing](/img/12/a330b5e77921bbfa8e96fcbc660daa.png)
[Video] Bayesian inference in linear regression and R language prediction of workers' wage data | data sharing
随机推荐
GDB的使用
[andorid] realize SPI communication between kernel and app through JNI
Interface idempotency problem
NPM err code 500 solution
Search ideas and cases of large amount of Oracle redo log
PG SQL intercepts the string to the specified character position
kettle庖丁解牛第16篇之输入组件周边讲解
Set Jianyun x Feishu Shennuo to help the enterprise operation Department realize office automation
校园外卖系统 - 「农职邦」微信原生云开发小程序
Oracle index status query and index reconstruction
Bottomsheetdialogfragment + viewpager + fragment + recyclerview sliding problem
Processbuilder tool class
Solve tp6 download error course not find package topthink / think with stability stable
Analysis of cluster component gpnp failed to start successfully in RAC environment
At the same time, the problems of height collapse and outer margin overlap are solved
[point cloud series] Introduction to scene recognition
SAP ui5 application development tutorial 72 - trial version of animation effect setting of SAP ui5 page routing
Detailed explanation and usage of with function in SQL
Innobackupex incremental backup
RTOS mainstream assessment