Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior in Java with unsyncronized access in a multithreading program

I change a value that is used to determine when a while-loop terminates in a seperate thread.
I don't want to know how to get this working. If I access the variable test only through synchronized getters/setters it works as expected..

I would have expected, if some read/write commands are lost due to concurrency the program sometimes does not terminate, but it never does. Thats what confuses me..
I would like to know why the program never terminates, without the print-command. And I would like to understand why the print-command changes anything..

     

    public class CustomComboBoxDemo  {
        public static boolean test = true;
        public static void main(String[] args) {
            Thread user =new Thread(){
                @Override
                public void run(){
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {}
                    test=false;
                }
            };
            user.start();
            while(test) {
                System.out.println("foo"); //Without this line the program does not terminate..
            }
        }
    }

like image 266
Heinrich Ody Avatar asked Jan 05 '12 14:01

Heinrich Ody


1 Answers

The most likely explanation is that the variable is only read once, turning the while into an infinite loop (or a no-op). Since you haven't declared test as volatile, the compiler is allowed to perform such an optimization.

Once you call an external function from within the loop, the compiler can no longer prove that test remains invariant across loop iterations, and doesn't perform the optimization.

like image 137
NPE Avatar answered Oct 09 '22 12:10

NPE