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模型的实现原理对于编写多线程程序非常重要,可以帮助我们避免出现并发相关的问题。

目录
相关文章
|
8月前
|
Java 编译器 开发者
【并发编程的艺术】Java内存模型的顺序一致性
首先明确一点,顺序一致性内存模型是一个被理想化了的理论参考模型,提供了很强的内存可见性保证。其两大特性如下: 1)一个线程中的所有操作,必须按照程序的顺序来执行(代码编写顺序) 2)无论程序是否同步,所有线程都只能看到一个单一的操作执行顺序。每个操作都必须原子执行且立即对所有线程可见。
131 0
|
2天前
|
存储 算法 安全
深入探究Java内存模型
深入探究Java内存模型
|
6月前
|
存储 缓存 Java
并发编程系列教程(05) - Java内存模型
并发编程系列教程(05) - Java内存模型
34 0
|
10月前
|
存储 缓存 Java
Java内存模型—工作流程、volatile原理
最近在做项目的时候发现很多业务上用到了多线程,通过多线程去提升程序的一个运行效率,借此机会来复盘一下关于并发编程的相关内容。为什么要使用volatile?volatile底层原理是什么?JMM内存模型解决的是什么问题?带着这些问题来分享分享我的成果。
38029 4
|
12月前
|
存储 缓存 Java
高并发编程-重新认识Java内存模型(JMM)
高并发编程-重新认识Java内存模型(JMM)
87 0
|
存储 安全 Java
JVM学习.04. Java内存模型与线程模型
该篇内容主要介绍JVM如何实现多线程,多线程间由于共享和竞争数据而导致的一系列问题以及解决方案。
224 1
JVM学习.04. Java内存模型与线程模型
|
存储 Java 调度
并发编程(二)JMM模型
并发编程(二)JMM模型
104 0
|
存储 安全 Java
JVM技术之旅-了解介绍JMM模型
JVM技术之旅-了解介绍JMM模型
84 0
JVM技术之旅-了解介绍JMM模型
|
存储 缓存 Java
JUC并发编程学习(十六)谈谈java内存模型JMM
JUC并发编程学习(十六)谈谈java内存模型JMM
JUC并发编程学习(十六)谈谈java内存模型JMM
|
存储 缓存 安全
Java内存模型-底层原理
Java内存模型-底层原理