I am reading "Java Concurrency in practice" and looking at the example code on page 51.
This states that if a thread has references to a shared object then other threads may be able to access that object before the constructor has finished executing.
I have tried to put this into practice and so I wrote this code thinking that if I ran it enough times a RuntimeException("World is f*cked") would occur. But it isn't doing.
Is this a case of the Java spec not guaranting something but my particular implementation of java guaranteeing it for me? (java version: 1.5.0 on Ubuntu) Or have I misread something in the book?
Code: (I expect an exception but it is never thrown)
public class Threads {
private Widgit w;
public static void main(String[] s) throws Exception {
while(true){
Threads t = new Threads();
t.runThreads();
}
}
private void runThreads() throws Exception{
new Checker().start();
w = new Widgit((int)(Math.random() * 100) + 1);
}
private class Checker extends Thread{
private static final int LOOP_TIMES = 1000;
public void run() {
int count = 0;
for(int i = 0; i < LOOP_TIMES; i++){
try {
w.checkMe();
count++;
} catch(NullPointerException npe){
//ignore
}
}
System.out.println("checked: "+count+" times out of "+LOOP_TIMES);
}
}
private static class Widgit{
private int n;
private int n2;
Widgit(int n) throws InterruptedException{
this.n = n;
Thread.sleep(2);
this.n2 = n;
}
void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}
}
}
You don't publish the reference until after the constructor has finished, change Widgit like this:
private class Widgit{ // NOTE: Not class is not static anymore
private int n;
private int n2;
Widgit(int n) throws InterruptedException{
this.n = n;
w = this; // publish reference
Thread.sleep(2);
this.n2 = n;
}
void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}
Should now throw.
Edit: You should also declare the Widgit field as volatile:
private volatile Widgit w;
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