w3hJava

What, Why, When and How of Java, JavaFX and related technologies


Published May 16th, 2008

Is Compiler Optimization always good?

Last week, I made a presentation on Multi-threading in Java. Although I had covered this aspect in presentation but still wanted to blog more on the same. In multi-threading world, compiler optimization can cause serious problems. Check out this small piece of code

public class NonVolatileProblem extends Thread {

    ChangeFlag cf;

    public static void main(String[] args) {
        ChangeFlag cf = new ChangeFlag();
        NonVolatileProblem th1 = new NonVolatileProblem(cf);
        NonVolatileProblem th2 = new NonVolatileProblem(cf);
        th1.start();
        th2.start();
    }

    public void run() {
        cf.method1();
        cf.method2();
    }

    public NonVolatileProblem(ChangeFlag cf) {
        this.cf = cf;
    }
}

class ChangeFlag {

    boolean flag = false;

    public void method1() {
        flag = false;
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            System.out.println(”Don’t want to be here”);
        }
        if (flag) {
            System.out.println(”This can be reached “);
        }
        System.out.println(”Value of flag” + flag);
    }

    public void method2() {
        flag = true;
    }
}

Check out the reason in bold. Now if compiler optimizes the code and remove the part of if(flag), thinking that flag value will always be false. Then we have a situation here(FBI style of speaking :-D), because other thread can change its value and can make the flag value true.

Try to run this code 5-6 may be 10 times, you will be able to see the SOP statement “This can be reached“. Just for te sake of getting that, I have added sleep statement. Here what I got on my 3rd run of the code :)

Value of flag:false
This can be reached
Value of flag:true

Handling such type of situation is not difficult, specification says to add a word volatile before the variable flag which will tell the compiler not to optimize its code just by seeing some initial value or declaration.