简介
本文介绍Java中System.out.println对多线程的影响。
在Java中,我们经常会使用System.out.println打印数据来进行验证,但是它对多线程是有影响的。
多线程的死循环
代码示例
package com.example.a;
public class Demo {
private static boolean stopRequest = false;
public static void main(String[] args) {
Thread backgroundThread = new Thread(() -> {
while (!stopRequest) {
// System.out.println("11");
}
});
backgroundThread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stopRequest = true;
}
}
上边的代码会死循环,因为stopRequested一直是false。
结果如下:

原因分析
一开始主线程中的stopRequest;的变量值为false,创建了一个线程Thread-0,将initFlag复制到运行内存中,因为Thread-0在运行的时候initFlag一直都是false,因为while循环会一直运行,后面的线程Thread-1虽然改变了主内存里面stopRequest为true了,但是影响不了Thread-0运行内存中的stopRequest的值。因此Thread-0会一直在while中无限循环;
println导致跳出死循环
代码测试
package com.example.a;
public class Demo {
private static boolean stopRequest = false;
public static void main(String[] args) {
Thread backgroundThread = new Thread(() -> {
while (!stopRequest) {
System.out.println("11");
}
});
backgroundThread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stopRequest = true;
}
}
上边的代码会退出死循环,结果如下:


原因分析
println的源码如下:

加了println后,因为它是Synchronized加锁的,它会做如下操作:1.获得锁;2,清空工作流出来;3.从主内存拷贝对象副本到线程工作内存中;4.继续执行代码;5.刷新主内存数据;6.释放锁。
在刷新内存的过程中Thread-0线程的stopRequest就变成了true,所以就跳出了循环。

请先 !