views:

109

answers:

3
// The problem in Starter() 
// with any line before x = 5 ; for example System.out.println(" Anything");
// the result "x = 4" 

// but without the result = "x = 9"
// Why??????


    public class Starter extends Thread {

    private int x = 2;

    public static void main(String[] args)
    throws Exception{


        new Starter().wakeItSo();
    }

    Starter() {

        // Next line (with or without it)
        System.out.println("anything");    


        x = 5;
        start();

    }

    public void wakeItSo()
    throws Exception{

        //join();


        x = x -1;
        System.out.println("x =  "+  x);


    }

    public void run() {
        x *=2;
    }

}
+5  A: 

You have a race condition.

  • First the constructor of Starter runs, intializes x to 5 then starts a new thread.
  • Now there are two things that happen in different threads, but the the order in which they occur is not deterministic:
    • The new thread updates the value of x to 10.
    • In the main thread the constructor returns and then wakeItSo is called which access the current value of x and subtracts one from it.

If the operation in the new thread runs first you will probably get the result 9, if wakeItSo runs first you get 4. Which happens first is not well-defined and can change from run to run.

It appears that adding the print statement slows down the main thread enough so that the update to x in the new thread is more likely to execute first. You should be aware that this is not guaranteed to always be the case and you should not rely on this behaviour.

To make your program run deterministally you need to synchronize your two threads so that the first thread waits until the second thread has finished running (for example by using Thread.join).

Mark Byers
Hi - thanks for the great response. that's what i want "the principal of concurrency". Thank u......
MineIsMine
A: 

Change all references to x to use getter/setter methods, and then set a breakpoint on the setter method so that you can see everytime that the value is changed.

RyanHennig
Doesn't answer the question. In fact, the very act of running a debugger over code with a race condition can change how it behaves, and the problem could magically disappear while being examined in the debugger. Add to that: you want to rewrite half the app just to set a breakpoint, and you think this will uncover the problem in the existing code?
cHao
A: 

You're not creating a thread properly. The guts of the thread should go in its run() method, or else create a Runnable and use the Thread(Runnable) constructor.

Adam Crume
A thread that actually `extends Thread` can be created like this. In most cases, though, i hardly ever see it start or join itself. Usually the main thread (the one that ran `main`) will do that.
cHao
@cHao: I didn't see the run() method, just the call to start(). Sorry.
Adam Crume