Jay*_*esh 0 java multithreading volatile
我阅读了一些关于易变性线程缓存的文章,发现它没有例子太简短,所以初学者很难理解.
请帮我理解下面的程序,
public class Test {
int a = 0;
public static void main(String[] args) {
final Test t = new Test();
new Thread(new Runnable(){
public void run() {
try {
Thread.sleep(3000);
} catch (Exception e) {}
t.a = 10;
System.out.println("now t.a == 10");
}
}).start();
new Thread(new Runnable(){
public void run() {
while(t.a == 0) {}
System.out.println("Loop done: " + t.a);
}
}).start();
}
}
Run Code Online (Sandbox Code Playgroud)
当我做a变量volatile和运行我的程序那么一段时间后停止,但是当我删除volatile到a变量,那么它的推移,我的程序不会停止.
我对volatile的了解是"当变量被声明为volatile时,线程将直接读/写到变量内存而不是从本地线程缓存读/写.如果没有声明volatile,那么可以看到实际值更新的延迟."
另外,根据我对刷新缓存副本的理解,我认为程序会在一段时间内停止但是为什么在上面的程序中它继续运行而不是更新.
那么什么时候Thread引用它的本地缓存开始引用主副本或者用主副本刷新它的值?
如果我理解错了,请纠正我.
请用一些小代码片段或链接向我解释.
当变量声明为volatile时,线程将直接读/写到变量内存,而不是从本地线程缓存读/写.如果没有声明为volatile,则可以看到实际值更新的延迟.
首先,上述陈述是错误的.在机器代码级别上还有更多的现象与任何"线程局部变量高速缓存"无关.事实上,这个概念根本不适用.
为了给你一些特定的东西,JIT编译器将被允许转换你的代码
while(t.a == 0) {}
Run Code Online (Sandbox Code Playgroud)
成
if (t.a == 0) while (true) {}
Run Code Online (Sandbox Code Playgroud)
无论何时t.a不是volatile.Java内存模型允许将在数据争用中访问的任何变量视为访问线程是唯一存在的线程.因为很明显这个线程没有修改t.a,所以它的值可以被认为是一个循环不变量,并且不必重复检查...... 永远.
| 归档时间: |
|
| 查看次数: |
664 次 |
| 最近记录: |