jn1*_*1kk 3 java multithreading caching
读一本书,这个代码出现了:
public class Test {
private static boolean ready = false;
private static int number = 0;
public static class ListenerThread extends Thread {
public void run() {
while(!ready) {
Thread.yield();
}
System.out.println(number);
}
}
public static void main (String[] args) {
new ListenerThread().start();
number = 10;
ready = true;
}
}
Run Code Online (Sandbox Code Playgroud)
笔者相对较快地提到了我感到惊讶的要点.
他们说ListenerThread可能永远不会终止.我想了几天(在我的脑后),我唯一的结论是它可能被ListenerThread缓存.真的吗?将readyvolatile设置为解决问题(因为它不应该再缓存它)?
他们还说该程序可能会打印0.我现在明白Java可能会重新排序指令,因此在更改数字之前准备就绪为另一个线程.有没有任何方法(技术),除了将这些指令放在同步块中解决问题(在中央锁定值上)?我在想也许实现notify()/ wait(),但我觉得它会遭受同样的后果.避免这个问题的最佳方法是什么?
谢谢!
编辑:
我只是觉得我已经阅读了很多代码,并且很少有人为防止在多个线程中重新排序而烦恼.这有多常见?
我唯一的结论是它可能被ListenerThread缓存.真的吗?准备挥发性会解决问题(因为它不应该再缓存它)?
不仅缓存,而且JIT可以在线程永远不会更改它的基础上内联值.即它变得硬编码.
使用volatile可以防止这样的假设.它会强制它每次都读取缓存一致的副本.
我现在明白Java可能会重新排序指令,
不仅是Java,而且CPU可以重新排序指令.JIT知道CPU可以执行此重新排序和它很少需要的AFAIK,因为它假设CPU将做得很好.
BTW访问volatile变量也会阻止指令重新排序,因此readyvolatile可以解决这两个问题.
| 归档时间: |
|
| 查看次数: |
963 次 |
| 最近记录: |