Java内存可见性

作者: Chermack | 来源:发表于2020-10-05 20:26 被阅读0次

经常访问的变量会从主存读取到线程的高速缓冲区,导致不同线程间对数据的修改不能及时同步:


import java.util.concurrent.TimeUnit;

class TObject{
    public boolean b = false;
}

public class VisibilityTest {
    static boolean flag = true;
    static int num = 1;
    static String s = "a";
    static TObject tObject = new TObject();
    static Object object;
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (flag) {
                if (num==100) break;
                if (s.equals("b")) break;
                if (tObject.b) break;
                if (object!=null) break;
//                System.out.println("this can stop!");
            }
        });
        t1.start();
        TimeUnit.MILLISECONDS.sleep(10);
        flag = false;
        num = 100;
        s = "b";
        tObject.b = true;
        object=new Object();
    }
}

上方代码直接运行,t1线程始终无法读到main线程对值的修改正常结束。

要想同步t1和main的值。

  • 可以在变量前加volatile(易变的)关键字,使得每个线程对变量的访问不生成高速缓存,必须去主存读取和修改(保证了可见性但降低了性能)。
  • 遇到同步代码块或者同步方法(synchronized),也会更新线程私有高速缓冲内存的值,println是一个同步方法,上方注释//System.out.println("this can stop!");打开会导致更新缓冲区的值。
  • 若上方TimeUnit.MILLISECONDS.sleep(10); 修改为TimeUnit.MILLISECONDS.sleep(1);也会成功停止,因为高速缓冲还未形成,t1还是从主存中去读取的变量值。

注:
volatile和synchronized都可以实现线程间的可见性,但volatile没有上锁步骤,在实现可见性方面更轻量,但不能保证原子性。

相关文章

  • Java内存模型

    Java内存的可见性 Java内存模型(Java Memory Model)描述线程之间如何通过内存(memory...

  • 深度解析Java多线程的内存模型

    内部java内存模型 硬件层面的内存模型 Java内存模型和硬件内存模型的联系 共享对象的可见性 资源竞速 Jav...

  • JVM系列(3) JMM & volatile, synchro

    1.高速缓存, 主内存, 工作内存 2.Java内存模型 2.1 Java内存模型是围绕着并发编程中原子性、可见性...

  • Java 工程师成神之路(2018 年修订版)

    基础篇 1.1 JVM JVM内存结构 堆、栈、方法区、直接内存、堆和栈区别。 Java内存模型 内存可见性、重排...

  • java初入多线程5

    volatile 与java内存模型(JMM) java的内存模型都是围绕着原子性、有序性、还有可见性来展开的。 ...

  • java内存模型

    Java内存模型 Java线程之间的通信对程序员完全透明,内存可见性问题困扰程序员。 Java内存模型是一种抽象的...

  • 深入浅出 Java 并发编程 (2)

    本文目录 Java 内存模型与可见性 指令重排序 使用 volatile 关键字保证可见性 使用 synchron...

  • Java程序员需要掌握的技能

    一、基础篇 1.JVM JVM内存结构 堆、栈、方法区、直接内存、堆和栈区别 Java内存模型 内存可见性...

  • volatile详解

    Java内存模型 想要理解 volatile 为什么能确保可见性,就要先理解Java中的内存模型是什么 样的。 J...

  • JAVA内存可见性

    基本概念 java 的所有变量都存储在主内存中 每个线程有自己独的工作内存,保存了该线程使用到的变量副本,是对主内...

网友评论

    本文标题:Java内存可见性

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