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.
The fact that it's not guaranteed to be safe doesn't mean that things will necessary go wrong in your environment.
As far as I know, there is no evidence that this behaviour can be demonstrated on modern JVMs. However, there are evidences that some older JVMs were affected:
Also note that out-of-order execution can be caused not only by JVM, but also by CPU. However, memory model of x86 CPUs is quite conservative (Who ordered memory fences on an x86?), so that this behaviour cannot be caused by commonly used CPUs as well.
So, I think that it's unlikely that you would be able to demostrate this problem in a typical modern environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With