System.out.println()鲜为人知的秘密

1.先看一个案例

public class VolatileTest {
    public static boolean IS_TRUE = true;

    void m() {
        while (IS_TRUE) {
        }
        System.out.println("end");
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileTest tv = new VolatileTest();
        // 开启一个线程,
        new Thread(() -> tv.m()).start();

        Thread.sleep(1000);

        // 开启一个线程,修改静态变量
        new Thread(() -> IS_TRUE = false).start();
    }
}

程序未正常退出,陷入死循环了,原因是因为static无法保证工作区与主存区变量值的一致性。

2.在看下volatile

public class VolatileTest {
    public volatile static boolean IS_TRUE = true;

    void m() {
        while (IS_TRUE) {
        }
        System.out.println("end");
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileTest tv = new VolatileTest();
        // 开启一个线程,
        new Thread(() -> tv.m()).start();

        Thread.sleep(1000);

        // 开启一个线程,修改静态变量
        new Thread(() -> IS_TRUE = false).start();
    }
}

把变量用volatile修饰后,程序正常退出。这是因为第二个线程修改值后,第一个线程重新从主内存中获取了新值。

3.在while循环中使用System.out.println()

public class VolatileTest {
    public static boolean IS_TRUE = true;

    void m() {
        while (IS_TRUE) {
            System.out.println("while");
        }
        System.out.println("end");
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileTest tv = new VolatileTest();
        // 开启一个线程,
        new Thread(() -> tv.m()).start();

        Thread.sleep(1000);

        // 开启一个线程,修改静态变量
        new Thread(() -> IS_TRUE = false).start();
    }
}

程序也正常退出。疑惑了很久。最终打开源码

    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

发现因为println方法使用了synchronized。使用了 synchronized 上锁会做以下操作:

    1.获得同步锁;
    2.清空工作内存;
    3.从主内存拷贝对象副本到工作内存;
    4.执行代码(计算或者输出等);
    5.刷新主内存数据;
    6.释放同步锁。

值得一提的是volatile保证可见性,但不保证原子性。synchronized不且保证可见性,也保证原子性。

欢迎扫描下面图片关注我的个人公众号,回复“资源”可以获取java核心知识整理和经典书籍

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值