【发布时间】:2011-12-21 03:10:15
【问题描述】:
JCIP 警告我们不要发布不正确的对象(请参阅here)。如果一个对象是可变的,JVM 可能会决定在其初始化完成之前发布该对象。
所以代码
class Holder {public int h = 0;public Holder(int _h) {h = _h;}}
a = new Holder(10);
可能会变得有效
a = new Holder();
// inlined constructor
a.h = 10;
那么当不同线程访问a.h时,假设它永远不会为0,它可能会失败
// Thread #1 executing
a = new Holder();
// Thread #2 preempts
if (a != null) System.out.println("result: "+(100/a.h)); // oops...
我试图证明这个问题。但是我写的代码没有证明这一点。我做的是一个持有人
static class Holder {
int h = 0;
int dummy = 0;
public Holder(int h) {
// if construction takes time, maybe I have better chance creating the bug...
for (long i=0;i<1000*1000;i++) {
dummy += i*(-1+(i%2*2));
}
this.h = h;
}
public int verifyNonZero() {
return 1/h;
}
}
然后我运行了 1000 个线程,将 new Holder() 发布到静态 holder 变量,其他 1000 个线程运行 holder.verifyNonZero()。见full gist。
它对 Java 1.6 并没有真正的帮助,即使是 -server。
【问题讨论】:
-
也许您必须为 Java 打开一些优化标志。找他们?
-
@AbhinavSarkar 我认为
-server应该可以解决问题。知道我应该添加哪个附加标志吗? -
是的,我知道,但是您是否知道特定的相关标志(例如,增加永久空间对我没有帮助,会不会...)?
标签: java multithreading concurrency