gpt4 book ai didi

java - jvm重排序/可见性效果测试

转载 作者:搜寻专家 更新时间:2023-10-31 20:23:12 24 4
gpt4 key购买 nike

在写一些 java 文章时,我正在尝试重现 re-ordering在多线程环境中的非同步对象构造的情况下。在没有同步/volatiles/finals 的情况下构造一个重对象并且其他线程在构造函数调用后立即访问它的情况。这是我尝试的代码:

public class ReorderingTest {
static SomeObject<JPanel>[] sharedArray = new SomeObject[100];

public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
String name = "watcher" + i;
new Thread(new Watcher(name)).start();
System.out.printf("watcher %s started!%n", name);
}
}

static class Watcher implements Runnable {
private String name;

Watcher(String name) {
this.name = name;
}

public void run() {
while (true) {
int randomIndex = (int) (Math.random() * sharedArray.length);
SomeObject<JPanel> item = sharedArray[randomIndex];
if (item == null) {
//System.out.printf("sharedArray[%s]=null%n", randomIndex);
double r = 1 + Math.random() * 1000;
sharedArray[randomIndex] = new SomeObject<JPanel>(
new JPanel(), UUID.randomUUID().toString(), r, (float)r * 33, (long)r);
} else {
//System.out.printf("sharedArray[%s]=<obj>!%n", randomIndex);
if (item.value == null ||
(item.stringField == null) ||
(item.doubleField == 0) ||
(item.floatField == 0) ||
(item.longField == 0)
) {
System.err.printf("watcher %s sees default values: %s!%n", name, item);
} else {
// fully initialized! run new construction process
double r = 1 + Math.random() * 1000;
sharedArray[randomIndex] = new SomeObject<JPanel>(
new JPanel(), UUID.randomUUID().toString(), r, (float)r * 37, (long)r);

}
}
/*try {
TimeUnit.NANOSECONDS.sleep(randomIndex);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}*/
}
}
}

static class SomeObject<V> {
V value;
String stringField;
double doubleField;
float floatField;
long longField;

SomeObject(V value, String stringField, double doubleField, float floatField, long longField) {
this.value = value;
this.stringField = stringField;
this.doubleField = doubleField;
this.floatField = floatField;
this.longField = longField;
}

@Override
public String toString() {
return "SomeObject{" +
"value=" + value == null ? "null" : "<obj>" +
", stringField='" + stringField + '\'' +
", doubleField=" + doubleField +
", floatField=" + floatField +
", longField=" + longField +
'}';
}
}
}

-但到目前为止没有效果,我已经在不同的 2,4 和 8 核 Intel/AMD PC 上尝试过,运行了几个小时的测试 - 没有重新排序效果 - System.err.printf("watcher %s看到 ...") - 未调用,静态 sharedArray[randomIndex] 引用始终包含完全构造的值。

怎么了?如何重现这个?

最佳答案

这是一篇很好的文章,它应该展示在 x86 上重新排序(相当了不起,因为 x86 内存模型非常“安全”):

http://bartoszmilewski.wordpress.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

您的示例不会显示重新排序。编译器不会重新排序为“在分配之后但在构造之前存储对象引用”,因为构造函数可能会抛出异常,因此需要恢复引用。由于给定的保证,一些处理器可能会重新订购,但没有英特尔兼容的处理器。

关于java - jvm重排序/可见性效果测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6264466/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com