Josh and Neal wrote an excellent book with all of the Java Puzzlers through 2005, which is highly recommended, and occupies a place of honor in the stack of books in my bathroom.
The point of all of this is that occasionally, I will send Josh a multithreaded puzzler, and he will tell me it is no good, because you can't reproduce it every time. Here's one I sent him a couple of months ago.
It turns out that the following snippet of code displays the odd behavior 100% of the time under the JVM on my MacBook Pro (JDK 1.5.0_07), and won't display it at all on Linux. I haven't tried Windows. Can you figure out what the odd behavior will be? If you have an Intel-based Mac, you can probably even reproduce it.
class A {
volatile static int x = 1;
static {
B.y = 1;
}
}
class B {
volatile static int y = 2;
static {
A.x = 2;
}
}
public class Test {
public static void main(String [] args) {
Thread t1, t2;
(t1 = new Thread() {
public void run() {
A.x = 1;
}
}).start();
(t2 = new Thread () {
public void run() {
B.y = 2;
}
}).start();
try {
t1.join(); t2.join();
} catch (InterruptedException e) {}
}
}
3 comments:
I have jdk 1.6/windows, so I ran this code with a grain of salt. I got A.x=1 & B.y=2 (by adding prints after the joins), which I assume is not the odd behavior.
I'm guessing the odd behavior is A.x=2 and B.y=1. (Am I completely off?) The only way I can imagine this happening is that:
1. the static variables are initialized.
2. The threads are run.
3. The static blocks are reordered such that they set the final values.
Maybe this was allowed by your compiler/jmm because it knew that setting B.y doesn't effect x (and setting A.x doesn't effect y), so it found a way to optimize by reordering the actions?
Haha, you posted the answer. Ok, well I tried.
@Danny - I disagree with Danny here. I think reordering if atall it happens, will happens with respect to A.x or B.y but since both x and y are volatile, reordering should be taken care of. The only possible thing is the atomicity so in worst case the answer would either be A.x = 2 or B.y = 1.
Post a Comment