0

I have tested the following code many times and it always prints 1, Is it correct and why?

public class TestThread {
    static int a = 0;
    public static void main(String[] args) {
         Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println(a);
            }
        };
        thread.start();
        a = 1;
   }
}
Laf
  • 7,965
  • 4
  • 37
  • 52
biiyamn
  • 476
  • 3
  • 9
  • 2
    Well, you have a thread which keeps print variable `a`, whose value never changes (except from 0 to 1, at the very beginning). Why would you expect anything other than this behavior? – Tim Biegeleisen Dec 05 '18 at 13:50
  • Because you start the Thread at the bottom and set a to 1 ? what did you expect to happen? – Sonny Hansen Dec 05 '18 at 13:50
  • `Thread.start` is not blocking so the next statement is execute in 99% of the case before the print. There is 1% of the case where it might be possible that the tread start faster (but unlikely) – AxelH Dec 05 '18 at 13:51
  • 2
    https://stackoverflow.com/questions/48476916/happens-before-rules-in-java-memory-model – Oleksandr Pyrohov Dec 05 '18 at 13:52
  • What behavior did you expect? Please take some time to review [the help pages](http://stackoverflow.com/help) and [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Dec 05 '18 at 13:53
  • I expect an unpredictable output hwich can be 0 when the run method is executed before setting the variable a and 1 in opposite case – biiyamn Dec 05 '18 at 13:54
  • Try using the join() method on your thread, look at my answer for more details – rilent Dec 05 '18 at 14:15
  • Feel free to mark this answer as solved – rilent Sep 11 '19 at 14:16

2 Answers2

1

This is because the application doesn't wait for the thread to be over to continue its execution. It seems like most of the time the affectation

a = 1

is faster than the thread to be executed. That's why It is important in some cases to wait for your thread to be over.

If you set up a breakpoint to your a = 1 line, you will see 0 is printed.

Now try this :

public class TestThread {
    static int a = 0;
    public static void main(String[] args) throws InterruptedException {
         Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println(a);
            }
        };
        thread.start();
        thread.join();
        a = 1;
   }
}

Using the join() method, It will wait for thread to be finished.

You can also use the static Thread.sleep function but it is definitely not how I recommend to solve this issue since you can't know for sure how long it takes before your thread is complete.

thread.start();
Thread.sleep(100);
a = 1;
rilent
  • 659
  • 1
  • 6
  • 22
0

It takes a little while to start the thread that prints the value, so the 'main' thread sets a to 1 before the system.out is reached. If you add a little delay before a := 1; the system.out is reached before a := 1; and then 0 is printed:

    thread.start();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) { }
    a = 1;
Stefan
  • 2,395
  • 4
  • 15
  • 32