0

This is my simple program:

public class Test {
    public static Object obj = null;

    public static void main(String[] args) {
        obj = null;
        System.out.println("Start");
        MyThread myThread = new MyThread();
        myThread.start();
        while(obj == null) {
            //System.out.println("");
        }
        System.out.println("Stop");

    }
}

class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println("Thread 1");
        try {
            sleep(1);
        } catch (InterruptedException ex) {
        }
        System.out.println("Thread 2");
        Test.obj = new Object();
        System.out.println("Thread 3");
    } 
}

As you can see, I run MyThread thread and while loop of Test class. The loop checks if obj is null and if it is not, I stop it and print "2". MyThread assigns a value to obj. And now the problem:

Under Java 7 64-bit, in case of empty while loop, it is never stopped. However, if I uncomment System.out.print(""), "Stop" under the loop is printed. But for other statements inside the loop (e.g. int i = 1;) my program freezes. Under Java 32-bit everything works fine for all cases.

Could someone explain me this strange behaviour?

Thanks!

peter
  • 631
  • 2
  • 7
  • 18
  • Out of curiosity, in the case when your program freezes, do the prints "Thread1", "Thread2" "Thread3" come? – bobby May 18 '12 at 08:36

2 Answers2

3

Your code is not thread-safe. The assignment you make to Test.obj in the thread aren't guaranteed to be visible in the main thread without some form of synchronization.

Make that static variable private, and provide synchronized static getter/tester/setter methods would be one way of implementing this correctly (as long as all accesses go through these methods). Other alternatives exist.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • 1
    +1; btw: it will immediately work if you mark the variable `volatile`... – home May 18 '12 at 08:26
  • `volatile` is just too tricky. I'd avoid suggesting that unless the asker has a very, very clear grasp of synchronization issues. – Mat May 18 '12 at 08:27
2

Remember that that there is also volatile keyword in Java. In case of this particular example - Java caches your obj.

Xeon
  • 5,949
  • 5
  • 31
  • 52