I realized that this code:
public class TestThread3 extends Thread {
private int i;
public void run() {
i++;
}
public static void main(String[] args) {
TestThread3 a = new TestThread3();
a.run();
System.out.println(a.i);
a.start();
System.out.println(a.i);
}
}
results in 1 1 printed ... and i don't get it. I haven´t found information about how to explain this. Thanks.
results in 1 1 printed
So the first a.run(); is called by the main-thread directly by calling the a.run() method. This increments a.i to be 1. The call to a.start(); then is called which actually forks a new thread. However, this takes time to do so the i++; operation most likely has not started before the System.out.println(...) call is made so a.i is still only 1. Even if the i++ has completed in the a thread before the println is run, there is nothing that causes the a.i field to be synchronized between the a thread and the main-thread.
If you want to wait for the spawned thread to finish then you need to do a a.join(); call before the call to println. The join() method ensures that memory updates done in the a thread are visible to the thread calling join. Then the i++ update will be seen by the main-thread. You could also use an AtomicInteger instead of a int which wraps a volatile int and provides memory synchronization. However, without the join() there is still a race condition between the a thread doing the increment and the println.
// this provides memory synchronization with the internal volatile int
private AtomicInteger i;
...
public void run() {
i.incrementAndGet();
}
...
a.start();
// still a race condition here so probably need the join to wait for a to finish
a.join();
System.out.println(a.i.get());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With