Listing 3.15. Class at Risk of Failure if Not Properly Published.
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}
My first question is why javac not optimize if (n != n)
?
The following is my demo for the example
public class TestSync {
private int n;
public TestSync(int n) {
this.n = n;
}
public void assertSanity() {
if(n!=n)
throw new AssertionError("This statement is false");
}
private static TestSync test;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
if(test == null) test = new TestSync(2);
else test = null;
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
if(test != null)
try {
test.assertSanity();
} catch (NullPointerException e) {
}
}
}
}).start();
}
}
And my second question is Did I do the right thing? Because it occurs no exception when I run the demo.
UPDATE
1.Addition to my first question:
javap -c TestSync.class
public void assertSanity();
Code:
0: aload_0
1: getfield #3 // Field n:I
4: aload_0
5: getfield #3 // Field n:I
8: if_icmpeq 21
11: new #4 // class java/lang/AssertionError
14: dup
15: ldc #5 // String This statement is false
17: invokespecial #6 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
20: athrow
21: return
I thinked javac would optimize if(n!=n)
to if(false)
and shrink it.
2.Why I still add try{}catch(NullPointerException e)
after if(test != null)
?
Because I think field test
may be setted null
by the other thread after if(test!=null)
.