令人迷惑的volatile例子(一)
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 35/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- java
- Domain
- documentation
Research direction
Start by locating the repository note or example that discusses Java volatile visibility and compare it with the two examples in this issue. Clarify why the examples behave differently across compiler and hardware contexts, and ensure the note explains why volatile remains necessary for portable Java code; no target file or test is named.
Written by the indexing model from the issue text.
Description
通常情况下关于volatile用法的正确例子是这样:
private volatile boolean flag = true;
@org.junit.Test
public void testVolatile() {
new Thread(() -> {
try {
System.out.println("子线程启动");
TimeUnit.SECONDS.sleep(3);
flag = false;
System.out.println("flag false");
} catch (InterruptedException ignore) {
}
}).start();
while (flag) {
}
}
结果也确实如此,不会导致死循环,与之相反如果把volatile去掉:
private boolean flag = true;
的确会死循环,于是我们得出结论:必须使用volatile保证内存可见性。然而事实并不是如此,下面的例子只在while (flag)中加入一句无关痛痒的代码:
private boolean flag = true;
@org.junit.Test
public void testVolatile() {
new Thread(() -> {
try {
System.out.println("子线程启动");
TimeUnit.SECONDS.sleep(3);
flag = false;
System.out.println("flag false");
} catch (InterruptedException ignore) {
}
}).start();
while (flag) {
System.out.print(1);
}
}
你会发现,现在也不会死循环了。
其实,在X86平台上,即使不使用memory barrier处理器也会保证变量修改的全局可见。参考:
Does a memory barrier ensure that the cache coherence has been completed?
上面那个例子死循环的原因其实是JVM编译器优化,将代码实际上变成了(加上volatile或打印阻止了这种优化):
if (flag) {
while (true) {}
}
参考:请问R大 有没有什么工具可以查看正在运行的类的c/汇编代码
那X86既然已经保证了全局可见,为什么我们还要使用volatile?Java毕竟是跨平台的语言,也许就会运行在不保证全局可见的处理器上,那时就会出错了。
所以如果你没在这种场景下用volatile,并不是你写的对,而是你恰好把代码跑在了X86上而已。
- Dominant language
- Java
- Stars
- 2k
- Forks
- 717
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from seaswalker/jdk-sourcecode-analysis
-
一种从值转为枚举的方法 Open
Difficulty 2/5 1-3 hours Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 20/100
-
JMM和Linux内存屏障定义 Open
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
令人迷惑的volatile例子(三) Open
Difficulty 5/5 Over a week Newbie friendliness 18/100
-
令人迷惑的volatile例子(二) Open
Difficulty 5/5 Over a week Newbie friendliness 25/100
All issues in seaswalker/jdk-sourcecode-analysis
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
bug needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 1/5 Under an hour Newbie friendliness 94/100
objectionary/hone-maven-plugin#1061 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
spring-projects/spring-modulith#1895 ·