简介
本文介绍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,所以就跳出了循环。
请先
!