In the verification of volatile keyword, we found this scenario: in the code, if the comment line is executed or not, the final result is different.
When the printed information is commented out, the business logic will be executed in a dead loop, which is understandable
When the comment is released, the business logic can read the value modified by the child thread
public class VolatileTest {
public static void main(String[] args) {
VolatileThread thread = new VolatileThread();
thread.start();
while (true) {
// System.out.println("thread.isFlag():" + thread.isFlag());
if (thread.isFlag()) {
System.out.println("----------------------");
break;
}
}
}
public static class VolatileThread extends Thread {
public boolean flag = false;
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("flag= " + flag);
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
}
Comment the result of South
Result of execution of South
The main reason is implementation System.out.println Compared with other statements, it is very slow and involves a lot of internal operations, resulting in CPU cache failure. So the effect is equivalent to let the main thread finally have a chance to see the flag changed.
You can add count to compare (when I have output on my machine, I execute 70399 cycles, when I have no output, I execute 801053907 cycles).
In the end, we need to use the volatile keyword to deal with the visibility problem
public volatile boolean flag = false;
The essence of Sout is synchronous execution. You can see it by looking at the JDK source code, which is equivalent to partial synchronization in disguise.
To print, it is recommended to use log frames such as log4j and logback. You will find that the result is almost the same whether you annotate or not.