I was trying to create a few scenarios to demonstrate visibility issues while sharing variable across threads. And I noticed that in almost all the cases I tested, if inside run() I added a System.out.println() statement in the same block of code where I am using the shared variable, the visibility issue is not producible. I will provide one example:
Configuration details - Oracle Java6 64bit, Eclipse Juno SR 2
1)WITH VISIBILITY ISSUE:
public class NoVisibility_Demonstration extends Thread {
boolean keepRunning = true;
public static void main(String[] args) throws InterruptedException {
NoVisibility_Demonstration t = new NoVisibility_Demonstration();
t.start();
Thread.sleep(1000);
t.keepRunning = false;
System.out.println("keepRunning is false");
}
public void run() {
int x = 1;
while (keepRunning)
{
//System.out.println("If you uncomment this line, the code will work without the visibility issue");
x++;
}
System.out.println("x:"+x);
}
}
OUTPUT: The thread keeps running infinitely
THE SAME CODE AS ABOVE, WITH THE UNCOMMENTED println() STATEMENT IN THE run()
OUTPUT:
...
If you uncomment this line, the code will work without the visibility issue
If you uncomment this line, the code will work without the visibility issue
If you uncomment this line, the code will work without the visibility issue
x:19391
keepRunning is false
Since I noticed similar behavior in all the examples I tried, I am wondering if there is any data integrity check by JVM before any I/O operation.
PrintWriter is synchronized
public void println(String x) {
synchronized(this) {
this.print(x);
this.newLine();
}
}
Two sequential calls of System.out.println()
in main thread and in second thread create a synchronization order between two threads. That means that all actions (in your case it is variable update), that happened in main thread before releasing a monitor (exiting synchronized method) will be seen by the code, executed in second thread after it acquires a monitor (enter synchronized method).
In simple words, yes, calling System.out.println()
makes this synchronization.
This behaviour is implementation specific. In OpenJDK, println
's body is synchronized altough the API does not state that it is.
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