The question of thread safe behaviour relating to System.out.println()
normally comes up when someone has an intermittent problem in their code, and when they add a 'debug' println()
the problem goes away. The cache-coherent store that happens with the println's synchronization makes the bug 'invisible'.... but....
...it does not make the bug go away, it just makes it much, much less likely to happen, and for practical purposes, the bug is gone. But, you remove the println and the bug comes back.
In your code example, you have the two threads with a boolean. When I read your code, I interpret that the desired behaviour (to be thread safe) would be that in the following thread 2:
Thread 2:
System.out.println();
while(flag){
System.out.println(); // PL2 - PrintLine2
}
The intention of the code is that the second println should only happen when the flag is true.
In other words, in the loop, if the line was (add the flag value to the println):
System.out.println(flag); // PL2 - PrintLine2
Then the printed result should always be 'true' - never false.
This would appear to be the case, but that is only because this code is trivial.... if there was anything of any significant 'work' happening before the println, then it becomes more obvious..... for example, consider the following:
public class ThreadPrintln {
private static boolean flag = true;
private static class ThreadTwo implements Runnable {
@Override
public void run() {
long sum = 1L;
System.out.println("Thread2Start");
while (flag) {
// non-trivial code
for (int i = 0; i < 100000; i++) {
sum += i;
}
System.out.println(flag); // PL2 - PrintLine2
}
System.out.println("Sum is " + sum);
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new ThreadTwo());
t.start();
System.out.println("Main About to wait");
Thread.sleep(1000);
System.out.println("Main about to set");
flag = false;
System.out.println("Main about to join");
t.join();
System.out.println("Main about to exit");
}
}
When I run this on my laptop I get the result:
true
true
true
....
.... many true values
....
true
true
true
Main about to set
Main about to join
false
Sum is 38724612750001
Main about to exit
** Note that it printed 'false' on the second to last line!!**
The use of the println() does not make the logic thread safe!
As the 'non-trivial' code becomes less and less, it reduces the chances that you will get bad behaviour, but it does not eliminate it. Removing the 'non trivial' code does not eliminate the chances if thread mis-behaviour, it only makes it so little that you are not likely to see it when testing it..... but, at some point it will misbehave.