当前位置:网站首页>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
边栏推荐
- [machine learning] Note 4. KNN + cross validation
- SAP ui5 application development tutorial 72 - animation effect setting of SAP ui5 page routing
- Exemple de méthode de réalisation de l'action d'usinage à point fixe basée sur l'interruption de déclenchement du compteur à grande vitesse ob40 pendant le voyage de tia Expo
- Why do you need to learn container technology to engage in cloud native development
- RAC environment error reporting ora-00239: timeout waiting for control file enqueue troubleshooting
- Core concepts of microservice architecture
- ACFs file system creation, expansion, reduction and other configuration steps
- QT调用外部程序
- Oracle generates millisecond timestamps
- Migrating your native/mobile application to Unified Plan/WebRTC 1.0 API
猜你喜欢
[point cloud series] neural opportunity point cloud (NOPC)
Static interface method calls are not supported at language level '5'
[point cloud series] so net: self organizing network for point cloud analysis
AI21 Labs | Standing on the Shoulders of Giant Frozen Language Models(站在巨大的冷冻语言模型的肩膀上)
TIA博途中基于高速计数器触发中断OB40实现定点加工动作的具体方法示例
Detailed explanation of ADB shell top command
Explanation of input components in Chapter 16
SHA512 / 384 principle and C language implementation (with source code)
Handling of high usage of Oracle undo
Window analysis function last_ VALUE,FIRST_ VALUE,lag,lead
随机推荐
Oracle index status query and index reconstruction
浅谈js正则之test方法bug篇
Migrating your native/mobile application to Unified Plan/WebRTC 1.0 API
校园外卖系统 - 「农职邦」微信原生云开发小程序
PG library to view the distribution keys of a table in a certain mode
Oracle kills the executing SQL
Using open to open a file in JNI returns a - 1 problem
【重心坐标插值、透视矫正插值】原理以及用法见解
QT调用外部程序
RAC environment error reporting ora-00239: timeout waiting for control file enqueue troubleshooting
What does the SQL name mean
Oracle database recovery data
TIA博途中基於高速計數器觸發中斷OB40實現定點加工動作的具體方法示例
[Journal Conference Series] IEEE series template download guide
Double pointer instrument panel reading (I)
Common analog keys of ADB shell: keycode
JS time to get this Monday and Sunday, judge the time is today, before and after today
Lenovo Saver y9000x 2020
sys. dbms_ scheduler. create_ Job creates scheduled tasks (more powerful and rich functions)
Oracle job scheduled task usage details