After surfing the web, I am still confused about the following thread behavior. I am aware that static variables are shared within the same classloader, however there's sth definitely missing in this extract:
public class parallelCounter {
public static final int N = 100000000;
public static int j = 0;
public static void inc() {
for (int i = 0; i < N; i++) {
j++;
}
System.out.println(j); // 10000000
}
}
class parallelCounterDemo {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
parallelCounter.inc();
}
});
t1.start();
System.out.println(parallelCounter.j); // 0 Why?
}
}
Static variables belong to the class instead of to the individual instances, so it doesn't change in every instance - it only exists in one place. It may give the appearance of changing in every instance, but that is because there is only one variable.
Static variables are indeed shared between threads, but the changes made in one thread may not be visible to another thread immediately, making it seem like there are two copies of the variable.
Static variable is a shared resource, which can be used to exchange some information among different threads.
Each thread will share the same static variable which is mostly likely a global variable. The scenario where some threads can have wrong value is the race condition (increment isn't done in one single execution rather it is done in 3 assembly instructions, load, increment, store).
There are two things to note here:
Your code has a race-condition in that the state when printing depends on the execution speed of the two independent threads. Most times t1
will not even have started executing inc
when your println
executes. You might try adding a sleep(100)
or something after t1.start
.
You have to take care that not all changes to variables made by one thread will be instantly visible to other threads - this is a pretty complex topic where you have to check which constucts will result in data-synchronization between threads. For you example the easiest way could be to declare j
as public static volatile int
.
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