当前位置:网站首页>How can volatile memory be visible? Must it be invisible without volatile? "
How can volatile memory be visible? Must it be invisible without volatile? "
2020-11-06 01:17:33 【Bugstack wormhole stack】
author : Little brother Fu
Blog :https://bugstack.cn
precipitation 、 Share 、 grow up , Let yourself and others have something to gain !
One 、 Experience of yard
Are you a tough person ?
In the past, people who could bear hardships mostly referred to the hardships of physical labor , But now, being able to bear hardships already includes too many dimensions , Include : Read and study & The pain of loneliness
、 Think deeply & Mental pain
、 Self discipline habit & The pain of practice
、 Self control & The pain of giving up
、 Bow your head and be a man & The bitterness of dignity
.
Although these are in front of us , But most people still like to eat simple bitter . Stay up late 、 Day after day 、 Repeat yesterday 、CRUD, Finally, the body becomes fat 、 Physical decline 、 Lack of ability 、 Hold yourself and cry ! So some bitterness can not eat without eating , If you want to eat, you should eat the bitterness with growth value .
Did you blog today ?
If a little thing can persist 5 In the above , Then you must be a great man . Yes , It's amazing . The most difficult thing for a person is to think clearly but can't do it , Or occasionally, you can't do it for a long time .
In fact, most of the partners on the road to R & D , They all know that they should work hard , But clearly made a good decision is not to hold on for long . It's like if you've ever thought about blogging about technology , Do technology accumulation . It's not until one day that you're stuck in a dilemma by a bottleneck , But it's really hard to break at this time !
Two 、 Interview questions
Thank you plane , Notes
, Airplanes take advantage of the weekend , Eat hot pot . I went to have tea with the interviewer again !
Thank you plane : hi , I'm here , here , here .
interviewer : Why are you here again , I've learned a lot recently ?
Thank you plane : Still want to come to the big factory , Don't be shy , Meet me !
interviewer : I seem to be your make-up teacher … Now that it's here , Just ask you !volatile What are the ?
Thank you plane : ah ,volatile It ensures the visibility of variables to all threads .
interviewer : that volatile Can we solve the problem of atomicity ?
Thank you plane : Can not be !
interviewer : that volatile How to realize the underlying principle of ?
Thank you plane :…, this ! interviewer , I just asked two questions and then I dropped thunder , You don't have to be busy at home ?
interviewer : None of your business !
3、 ... and 、volatile Explain
1. Visibility case
public class ApiTest {
public static void main(String[] args) {
final VT vt = new VT();
Thread Thread01 = new Thread(vt);
Thread Thread02 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException ignore) {
}
vt.sign = true;
System.out.println("vt.sign = true notice while (!sign) end !");
}
});
Thread01.start();
Thread02.start();
}
}
class VT implements Runnable {
public boolean sign = false;
public void run() {
while (!sign) {
}
System.out.println(" You are bad ");
}
}
This code , Two threads operate on a variable , The program expects to be sign
In a thread Thread01 Operated by vt.sign = true
when ,Thread02 Output You are bad .
But in fact, this code will never output You are bad , It's been in a dead circle . Why is that ? Next, we will explain and verify step by step .
2. add volatile keyword
We put sign Keywords plus volatitle describe , as follows :
class VT implements Runnable {
public volatile boolean sign = false;
public void run() {
while (!sign) {
}
System.out.println(" You are bad ");
}
}
test result
vt.sign = true notice while (!sign) end !
You are bad
Process finished with exit code 0
volatile Keywords are Java The lightest synchronization mechanism provided by virtual machines , It appears as a modifier , Used to modify variables , But it doesn't include local variables
Adding volatile The key word , The program will produce the expected output You are bad . From us to volatile We can know that .volatile Keywords are JVM The lightest synchronization mechanism available , Used to modify variables , Used to ensure the visibility of variables to all threads .
After modifying, you can make the field visible in the program , Then, after the attribute has been modified, the value , Can make corresponding response in another thread in time .
3. volatile How to ensure the visibility of
3.1 nothing volatile when , Memory changes
The first is when sign No, volatitle When decorating public boolean sign = false;
, Threads 01 Operate on variables , Threads 02 You don't get the value of the change . So the program will not output the result “ You are bad ”
3.2 Yes volatile when , Memory changes
When we use variables volatile When decorating public volatile boolean sign = false;
, Threads 01 When you operate on a variable , Will change the value of the variable forced refresh to main memory . When a thread 02 Get the value when , Will put their own memory sign Value expired , Then read it from main memory . So add keywords after the program as expected output results .
4. Decompilation and detoxification visibility
There's deep technical knowledge like this , The best way to do that is to understand the principles , See what it does to ensure memory visibility operations .
4.1 see JVM Instructions
Instructions :javap -v -p VT
public volatile boolean sign;
descriptor: Z
flags: ACC_PUBLIC, ACC_VOLATILE
org.itstack.interview.test.VT();
descriptor: ()V
flags:
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #2 // Field sign:Z
9: return
LineNumberTable:
line 35: 0
line 37: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lorg/itstack/interview/test/VT;
public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field sign:Z
4: ifne 10
7: goto 0
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #4 // String You are bad
15: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: return
LineNumberTable:
line 40: 0
line 42: 10
line 43: 18
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 this Lorg/itstack/interview/test/VT;
StackMapTable: number_of_entries = 2
frame_type = 0 /* same */
frame_type = 9 /* same */
}
from JVM There's only a lot more to be found in the script ,ACC_VOLATILE
, There are no other points . therefore , You can't see how visibility is achieved .
4.2 Look at the assembly instructions
adopt Class File view assembly , Need to download hsdis-amd64.dll file , Copied to the JAVA_HOME\jre\bin\server Under the table of contents
. Download resources as follows :
- http://vorboss.dl.sourceforge.net/project/fcml/fcml-1.1.1/hsdis-1.1.1-win32-amd64.zip
- http://vorboss.dl.sourceforge.net/project/fcml/fcml-1.1.1/hsdis-1.1.1-win32-i386.zip
The other is to execute orders , Include :
- Basic instructions :
java -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
- Specify print :
-XX:CompileCommand=dontinline, Class name . Method name
- Specify print :
-XX:CompileCommand=compileonly, Class name . Method name
- Output location :
> xxx
End use :java -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=dontinline,ApiTest.main -XX:CompileCommand=compileonly,ApiTest.mian
Instructions can be in IDEA Medium Terminal Use in , You can also go to DOS Use in black window
in addition , For easier use , We can configure instructions to idea Of VM options in , Here's the picture :
When the configuration is complete , The results are as follows :
Loaded disassembler from C:\Program Files\Java\jdk1.8.0_161\jre\bin\server\hsdis-amd64.dll
Decoding compiled method 0x0000000003744990:
Code:
Argument 0 is unknown.RIP: 0x3744ae0 Code size: 0x00000110
[Disassembling for mach='amd64']
[Entry Point]
[Constants]
# {method} {0x000000001c853d18} 'getSnapshotTransformerList' '()[Lsun/instrument/TransformerManager$TransformerInfo;' in 'sun/instrument/TransformerManager'
# [sp+0x40] (sp of caller)
0x0000000003744ae0: mov r10d,dword ptr [rdx+8h]
0x0000000003744ae4: shl r10,3h
0x0000000003744ae8: cmp r10,rax
0x0000000003744aeb: jne 3685f60h ; {runtime_call}
0x0000000003744af1: nop word ptr [rax+rax+0h]
0x0000000003744afc: nop
[Verified Entry Point]
0x0000000003744b00: mov dword ptr [rsp+0ffffffffffffa000h],eax
0x0000000003744b07: push rbp
0x0000000003744b08: sub rsp,30h ;*aload_0
; - sun.instrument.TransformerManager::getSnapshotTransformerList@0 (line 166)
0x0000000003744b0c: mov eax,dword ptr [rdx+10h]
0x0000000003744b0f: shl rax,3h ;*getfield mTransformerList
; - sun.instrument.TransformerManager::getSnapshotTransformerList@1 (line 166)
0x0000000003744b13: add rsp,30h
...
The result of running is assembly instruction , There are a lot of them . We're only looking at the key parts :
0x0000000003324cda: mov 0x74(%r8),%edx ;*getstatic state
; - VT::run@28 (line 27)
0x0000000003324cde: inc %edx
0x0000000003324ce0: mov %edx,0x74(%r8)
0x0000000003324ce4: lock addl $0x0,(%rsp) ;*putstatic state
; - VT::run@33 (line 27)
In the compiled assembly instructions , Yes volatile Keywords and no volatile keyword , The main difference is that there is one more lock addl $0x0,(%rsp)
, That is to say lock The prefix instruction of .
lock Instructions Equivalent to one Memory barrier , It guarantees the following three points :
- Write the processor's cache to memory .
- When reordering, you cannot reorder subsequent instructions to the position in front of the memory barrier .
- If it is a write action, it will cause the corresponding memory in other processors to be invalid .
that , there 1、3 It's used to guarantee the modified variables , Ensure memory visibility .
5. No addition volatile Is it visible
If there is doubt, there must be verification
Let's revise the example again , stay while (!sign)
Add an execution code to the loop body , as follows ;
class VT implements Runnable {
public boolean sign = false;
public void run() {
while (!sign) {
System.out.println(" Hello ");
}
System.out.println(" You are bad ");
}
}
After the amendment, it was removed volatile
keyword , And in while Add a piece of code to the loop . Now the running result is :
...
Hello
Hello
Hello
vt.sign = true notice while (!sign) end !
You are bad
Process finished with exit code 0
how , You can see it again !
This is because there is no volatile When decorating ,jvm We will also try to ensure visibility . Yes volatile When decorating , Make sure you have visibility .
Four 、 summary
- Finally, let's sum up volatile, It? , It will control the modified variables to actively refresh the value to main memory in memory operation ,JMM This thread will correspond to CPU Memory settings expired , Read the latest value from main memory .
- that ,volatile How to prevent instruction rearrangement is also a memory barrier ,volatile The memory screen failure is to add one before and after the read and write operation StoreStore barrier , That's four places , To ensure that the instructions behind the memory barrier cannot be reordered to the position before the memory barrier when reordering .
- in addition volatile It doesn't solve the problem of atomicity , If you need to solve the problem of atomicity , Need to use synchronzied perhaps lock, This part will be introduced in the following chapters .
5、 ... and 、 Series recommendation
- Is the grass , You're poisoning the code !
- HashMap Core knowledge , Disturbance function 、 Load factor 、 Split the expanded list
- ThreadLocal Technology stack deep learning
- A code review , Almost couldn't pass the probation period !
- Netty Copy desktop version of wechat

( Please indicate the author and source of this article WeChat official account :bugstack Wormhole stack | author : Little brother Fu )
版权声明
本文为[Bugstack wormhole stack]所创,转载请带上原文链接,感谢
边栏推荐
- C++ 数字、string和char*的转换
- C++学习——centos7上部署C++开发环境
- C++学习——一步步学会写Makefile
- C++学习——临时对象的产生与优化
- C++学习——对象的引用的用法
- C++编程经验(6):使用C++风格的类型转换
- Won the CKA + CKS certificate with the highest gold content in kubernetes in 31 days!
- C + + number, string and char * conversion
- C + + Learning -- capacity() and resize() in C + +
- C + + Learning -- about code performance optimization
猜你喜欢
-
C + + programming experience (6): using C + + style type conversion
-
Latest party and government work report ppt - Park ppt
-
在线身份证号码提取生日工具
-
Online ID number extraction birthday tool
-
️野指针?悬空指针?️ 一文带你搞懂!
-
Field pointer? Dangling pointer? This article will help you understand!
-
HCNA Routing&Switching之GVRP
-
GVRP of hcna Routing & Switching
-
Seq2Seq实现闲聊机器人
-
【闲聊机器人】seq2seq模型的原理
随机推荐
- LeetCode 91. 解码方法
- Seq2seq implements chat robot
- [chat robot] principle of seq2seq model
- Leetcode 91. Decoding method
- HCNA Routing&Switching之GVRP
- GVRP of hcna Routing & Switching
- HDU7016 Random Walk 2
- [Code+#1]Yazid 的新生舞会
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- HDU7016 Random Walk 2
- [code + 1] Yazid's freshman ball
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- Qt Creator 自动补齐变慢的解决
- HALCON 20.11:如何处理标定助手品质问题
- HALCON 20.11:标定助手使用注意事项
- Solution of QT creator's automatic replenishment slowing down
- Halcon 20.11: how to deal with the quality problem of calibration assistant
- Halcon 20.11: precautions for use of calibration assistant
- “十大科学技术问题”揭晓!|青年科学家50²论坛
- "Top ten scientific and technological issues" announced| Young scientists 50 ² forum
- 求反转链表
- Reverse linked list
- js的数据类型
- JS data type
- 记一次文件读写遇到的bug
- Remember the bug encountered in reading and writing a file
- 单例模式
- Singleton mode
- 在这个 N 多编程语言争霸的世界,C++ 究竟还有没有未来?
- In this world of N programming languages, is there a future for C + +?
- es6模板字符
- js Promise
- js 数组方法 回顾
- ES6 template characters
- js Promise
- JS array method review
- 【Golang】️走进 Go 语言️ 第一课 Hello World
- [golang] go into go language lesson 1 Hello World