JCIP warns us against improperly published objects (see here). If an object is mutable, the JVM might decide to publish the object before its initialization was finished.
So the code
class Holder {public int h = 0;public Holder(int _h) {h = _h;}}
a = new Holder(10);
could become effectively
a = new Holder();
// inlined constructor
a.h = 10;
then when different thread access a.h
, assuming it can never be 0, it could fail
// Thread #1 executing
a = new Holder();
// Thread #2 preempts
if (a != null) System.out.println("result: "+(100/a.h)); // oops...
I was trying to demonstrate this problem. But no code I wrote demonstrated it. What I did was a holder
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;
}
}
Then I ran 1000 threads publishing new Holder()
to a static holder
variable, and other 1000 threads running holder.verifyNonZero()
. See full gist.
It didn't really help with Java 1.6, even with -server
.