JMM原理篇

简介: JMM(Java Memory Model,Java内存模型)是Java中用于描述多线程程序中内存访问规则的规范。它定义了线程如何与主内存进行交互,以及线程之间如何共享变量。下面我们来深度解析JMM模型的底层实现,并且带上源码进行讲解。

Java中的JMM模型是建立在硬件的内存模型之上的,它通过一系列规则来限制编译器和处理器对内存的重排序,以保证多线程程序的正确性。JMM模型中最重要的概念是主内存和工作内存。

主内存是Java虚拟机中的一块内存区域,是所有线程共享的。它存储了所有的变量和对象,包括实例字段、静态字段和数组元素。主内存可以被多个线程同时访问。

工作内存是每个线程独有的一块内存区域,它存储了线程需要使用的变量和对象的副本。线程对变量的所有操作都是在工作内存中进行的,而不是直接在主内存中进行。

JMM模型通过一系列规则来描述线程如何与主内存进行交互。其中最重要的规则包括:原子性、可见性和有序性。

原子性保证了一个操作是不可分割的,要么完全执行,要么不执行。JMM模型保证了基本数据类型的读写操作具有原子性。而对于非原子性的操作,可以使用synchronized或者volatile关键字进行同步。

可见性保证了当一个线程修改了变量的值,其他线程能够立即看到这个修改。JMM模型通过在特定的时机刷新变量的值到主内存,以及在特定的时机将主内存中的变量值刷新到工作内存,来实现可见性。volatile关键字可以保证变量的可见性。

有序性保证了程序执行的顺序与代码的编写顺序一致。JMM模型通过禁止特定类型的重排序来保证有序性。volatile关键字和synchronized关键字都可以保证有序性。

下面是一段示例代码,我们来看看JMM模型在实际代码中的应用:

public class JMMExample {
    private static boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (!flag) {
                // do something
            }
            System.out.println("Thread 1 finished");
        });
        Thread thread2 = new Thread(() -> {
            flag = true;
            System.out.println("Thread 2 finished");
        });
        thread1.start();
        Thread.sleep(1000); // 确保thread1先启动
        thread2.start();
    }
}

在这个例子中,我们有两个线程,一个线程不断地检查flag的值,另一个线程修改flag的值。我们希望当flag的值变为true时,第一个线程能够停止循环并输出"Thread 1 finished"。

但是,由于JMM模型的可见性规则,第一个线程可能无法看到flag的修改,导致无法停止循环。为了解决这个问题,我们可以将flag声明为volatile

private static volatile boolean flag = false;

这样就能够保证变量的可见性,第一个线程能够正确地看到flag的修改。

以上是对JMM模型底层实现的简单解析,带上了代码示例。深入了解JMM模型的实现原理对于编写多线程程序非常重要,可以帮助我们避免出现并发相关的问题。

目录
相关文章
|
Java 编译器 开发者
【并发编程的艺术】Java内存模型的顺序一致性
首先明确一点,顺序一致性内存模型是一个被理想化了的理论参考模型,提供了很强的内存可见性保证。其两大特性如下: 1)一个线程中的所有操作,必须按照程序的顺序来执行(代码编写顺序) 2)无论程序是否同步,所有线程都只能看到一个单一的操作执行顺序。每个操作都必须原子执行且立即对所有线程可见。
158 0
|
3月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
67 0
|
3月前
|
安全 Java 程序员
深入浅出Java内存模型:探索JMM的奥秘
在Java编程世界中,理解其内存模型(JMM)是提升代码性能和确保线程安全的关键。本文将带你走进Java内存模型的大门,通过浅显易懂的方式揭示其工作原理,并指导你如何在实际开发中有效利用JMM来避免常见的并发问题。
|
4月前
|
Java 编译器
Java面试题:Java内存模型深度剖析,Java内存模型中的重排序(Reordering)现象,Java内存模型中的happens-before关系
Java面试题:Java内存模型深度剖析,Java内存模型中的重排序(Reordering)现象,Java内存模型中的happens-before关系
27 0
|
6月前
|
存储 算法 安全
深入探究Java内存模型
深入探究Java内存模型
|
存储 缓存 Java
Java内存模型—工作流程、volatile原理
最近在做项目的时候发现很多业务上用到了多线程,通过多线程去提升程序的一个运行效率,借此机会来复盘一下关于并发编程的相关内容。为什么要使用volatile?volatile底层原理是什么?JMM内存模型解决的是什么问题?带着这些问题来分享分享我的成果。
38079 4
|
存储 缓存 Java
高并发编程-重新认识Java内存模型(JMM)
高并发编程-重新认识Java内存模型(JMM)
114 0
|
存储 Java 调度
并发编程(二)JMM模型
并发编程(二)JMM模型
121 0
|
存储 缓存 Java
JUC并发编程学习(十六)谈谈java内存模型JMM
JUC并发编程学习(十六)谈谈java内存模型JMM
JUC并发编程学习(十六)谈谈java内存模型JMM
|
缓存 算法 Ubuntu
JMM到底如何理解?JMM与MESI到底有没有关系?
哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。 手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…
111 0
JMM到底如何理解?JMM与MESI到底有没有关系?