美文网首页
System.out.println()影响内存的可见性

System.out.println()影响内存的可见性

作者: Djbfifjd | 来源:发表于2021-03-02 21:22 被阅读0次

一、问题

public class TestVolatile implements Runnable {
    private boolean flag = false;
    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        System.out.println("flag---" + flag);
    }
    public static void main(String[] args) {
        TestVolatile tv = new TestVolatile();
        new Thread(tv).start();
        while (true) {
//            System.out.println("tv.isFlag()---" + tv.isFlag());
            if (tv.isFlag()) {
                System.out.println("hello main!");
                break;
            }
        }
    }
}

示例是实现了 Runnable 的自定义线程类,run() 将 flag 变为 true。main() 中启动子线程,主线程 while(true) 中判断 flag 为 true 输出“hello main!”。然而“hello main!”永远不会输出。原因是:

主线程中if (tv.isFlag())感知不到子线程中 flag 的变化。两个线程的数据是不会相互干扰的。也就是说这两个线程里面都存在一个 flag 的副本。真正的 flag 这个变量存放在主内存中,两个线程的工作内存中的 flag 变量只是副本。

二、synchronized 影响内存的可见性

放开代码中的注释行,“hello main!”输出了。这是为什么?

主线程感知到了子线程对 flag 的改动,说明这条打印语句已经影响到了内存可见性。如何影响的呢?答案就在源码里面:

原来 println 有一个上锁的操作。使用了 synchronized 上锁会做以下操作:

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

相关文章

  • System.out.println()影响内存的可见性

    一、问题 示例是实现了 Runnable 的自定义线程类,run() 将 flag 变为 true。main() ...

  • System.out.println()对于内存可见性的影响

    群友发了一段代码,说变量没有加volatile,但是依旧可见,代码大致如下:public class StopTh...

  • 多线程 | Volatile到底有什么用?

    Volatile的作用: 保持内存可见性.内存可见性:多个线程操作同一个变量,可确保写线程更新变量,其他读线程可以...

  • volatile

    目标 1、volatile如何保证内存可见性2、volatile如何禁止指令重排序3、内存屏障4、内存可见性5、关...

  • volatile

    volatile 内存唯一 可见性

  • Volatile原理总结

    内存可见性 内存可见性相关概念:线程对共享变量修改的可见性。当一个线程修改了共享变量的值,其他线程能够立刻得知这个...

  • 面试题收集

    Synchronized关键字和ReentrantLock的对比相同点:互斥性、内存可见性、可重入 不同点: ①R...

  • 关于多线程访问并操作共享数据的解决方案概述

    内存可见性 内存可见性(Memory Visibility)是指当某个线程正在使用对象状态 而另一个线程在同时修改...

  • 内存可见性

    Java虚拟机规范试图定义一种Java内存模型(JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,让Java程序...

  • 小编带您Volatile的详解

    volatile关键字修饰的共享变量主要有两个特点:1.保证了不同线程访问的内存可见性 2.禁止重排序 在说内存可...

网友评论

      本文标题:System.out.println()影响内存的可见性

      本文链接:https://www.haomeiwen.com/subject/mowxqltx.html