所有分类
  • 所有分类
  • 未分类

System.out.println对多线程的影响

简介

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

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录