Java内存模型中本地最终变量的语义?
|
以下代码有时会在我的
Windows-PC和Mac上打印“valueWrapper.isZero()”,
两者都以服务器模式运行JVM. 好的,这是因为值字段在ValueWrapper类中不是final, 所以某些线程可能会看到陈旧值为0. public class ConcurrencyApp {
private final Random rand = new Random(System.currentTimeMillis());
private ValueWrapper valueWrapper;
private static class ValueWrapper {
private int value;
public ValueWrapper(int value) {
this.value = value;
}
public boolean isZero() {
return value == 0;
}
}
private void go() {
while (true) {
valueWrapper = new ValueWrapper(randomInt(10,1024));
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (valueWrapper.isZero()) {
System.out.println("valueWrapper.isZero()");
}
}
});
thread.start();
}
}
private int randomInt(int min,int max) {
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
public static void printVMInfos() {
String vmName = System.getProperty("java.vm.name");
System.out.println("vm name: " + vmName);
int cores = Runtime.getRuntime().availableProcessors();
System.out.println("available cores: " + cores);
}
public static void main(String[] args) {
ConcurrencyApp app = new ConcurrencyApp();
printVMInfos();
app.go();
}
}
但是下面的修改呢,这里我使用了一个局部最终变量: private void go() {
while (true) {
final ValueWrapper valueWrapper = new ValueWrapper(randomInt(10,1024));
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (valueWrapper.isZero()) {
System.out.println("valueWrapper.isZero()");
}
}
});
thread.start();
}
}
看起来现在没有线程看到过时的值为0. 解决方法
我正在解决格雷没有提到的一点,但我会接受他,因为他的回答是正确的
你看到valueWrapper.isZero()返回true的原因有时是因为在调用start之后和运行之前valueWrapper正在改变布尔测试.如果您只创建了一个实例,那么Gray总是不会为零. 最终的ValueWrapper valueWrapper = new ValueWrapper(randomInt(10,1024));一直工作是因为字段是本地的线程(和方法),本地对象和匿名内部类的语义是将原始引用复制到类实例中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – GrizzlyServerFactory.createHttpServer和新的Griz
- Java Apache Poi,如何同时设置背景颜色和边框
- java – Datastax QueryBuilder插入语句
- JVM类加载过程
- java – 使用GSON创建JSON字符串
- 如何在Java 1.4中的BufferedReader和PrintWriter上设置超时
- java之方法的重载(overload)
- JavaFX PrintAPI错误的PaperSource
- SSH结合jquery实现三级联动效果
- java – OSGi中的OpenJPA没有找到MySQL JDBC Connector Bun
