Shi*_*gon 1 java multithreading volatile
我很抱歉,如果我对此做了一件坏事,但我有一个问题,这是这个问题的衍生产品:
为什么java 5+中的volatile不会将变量的缓存副本与主内存同步?
基本上,我想看看当volatile从a变量中消除时会发生什么.这是原始问题的代码,应用了我的修改:
public class Test {
//volatile static private int a;
static private int a;
static private int b;
public static void main(String [] args) throws Exception {
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
int tt = b; // makes the jvm cache the value of b
while (a==0) {
}
//some threads never get here (past the a==0 loop)
if (b == 0) {
System.out.println("error");
}
}
}.start();
}
b = 1;
a = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的笔记本电脑上发生的事情(Win 7 64,JVM build 1.7.0_04-b22)是没有的volatile,代码似乎永远运行(运行20分钟).添加一些控制台输出告诉我,虽然大多数的100个线程的根本终于看到了变化a,从0到1,总有几个左侧(小于10)继续做a==0循环.
我的问题是:这些线程最终会看到这种变化吗?如果是的话,与大多数相似的线程相比,花费数倍于数千倍的时间是正常的吗?怎么会?
这根本不是关于变量传播的速度; 机器代码可以使得甚至不尝试存储器写入.该值可以驻留在寄存器中.
无论如何,我的建议是不要探索破解Java代码的行为:无论如何它总是会有所不同.相反,学习如何正确编写同步程序.详细研究Java内存模型并了解其保证.JMM的保证远远不同于支持这些保证的实际JVM实现代码,而JMM是专门为JVM提供应用各种优化的自由而编写的.
作为一个特别尖锐的例子,破坏的代码的行为可以在其执行过程中发生变化,因为解释的或C1代码正在与C2代码及时替换.运行您引用的程序无需学习任何内容.
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |