Java内存模型(JMM)

一、JMM内存模型概述

JMM本身不真实存在,它仅仅描述的是一组约定或者规范。这些规范定义了多线程程序中的变量如何存储、访问和同步,以确保在多线程环境下变量的一致性和线程的安全性。

二、JMM内存模型的主要特点

原子性

一个操作或者一组操作要么全部执行要么全不执行

在Java中32位的基本类型默认其写入和读取操作是原子的,但是对于64位的long和double类型,在默认情况下,它们的操作不是原子性的,除非使用了volatile关键字修饰或者其他同步机制。

可见性

可见性是指一个线程对共享变量的修改能够及时对其他线程可见

在JMM中,通过volatile关键字,sychronized关键字或其他同步机制来保证变量的可见性

有序性

有序性指的是程序执行的顺序按照代码的先后顺序执行,但在现代处理器中,为了提高执行效率,指令可能也会被重新排列

JMM通过引入内存屏障来保证某些操作的执行顺序,内存屏障是一种特殊的指令,用于阻止编译器和处理器的优化,从而确保某些操作的执行顺序不会被改变

三、JMM内存模型的结构

JMM将内存分为主内存和工作内存:

主内存: 是所有线程都可以访问的一个公享区域,将所有变量(类实例字段,数组元素)都存储在主内存中,主内存中的变量对所有线程都是可见的。

工作内存: 是每个线程私有的存储空间,它保存了该线程使用的变量的副本,线程对变量的所有操作(读取、赋值等)都必须在自己的工作内存中进行,而不能直接读写主内存中的数据。

四、JMM内存模型的操作

JMM定义了八种基本操作来完成主内存与工作内存之间的交互:

  • lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
  • unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  • read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中。
  • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎。
  • assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收的值赋给工作内存的变量。
  • store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中。
  • write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

五、JMM内存模型的作用

解决了一致性和线程安全问题,通过定义变量的访问方式和同步机制,保证了多线程并发环境下多线程程序能够正确的执行,避免了由于缓存不一致,指令重排等问题导致的开发错误。

六、指令重排

什么是指令重排

指令重排是指编译器或处理器在执行程序时,为了提高执行效率,对代码中的指令进行重新排序的过程。这种重排是透明的,对程序员来说是不可见的,但在多线程环境下可能导致数据一致性和可见性问题。

编译器层面的指令重排

编译器在将源代码转换成机器码时,会进行多种优化,包括指令重排。这些优化旨在减少冗余代码、提升代码的执行效率。编译器会尝试在不改变程序逻辑的前提下,重新安排指令的执行顺序。

处理器层面的指令重排

现代处理器(如Intel和AMD的x86架构处理器)为了提升性能,通常会采用流水线、分支预测、乱序执行等技术。这些技术允许处理器在执行指令时,不严格按照程序中指令的顺序来执行,而是根据实际情况和预测结果来调度指令的执行。这种指令重排可以显著提升处理器的执行效率,但在多线程环境下可能引发问题。

多线程环境下的指令重排

在多线程程序中,如果多个线程共享同一个资源(如内存变量),那么指令重排就可能导致数据不一致的问题。例如,一个线程可能先更新了某个变量的值,然后释放了锁;而另一个线程可能在看到锁被释放后,立即读取该变量的值,但由于指令重排的影响,更新变量的操作可能还没有完成,导致读取到的是旧值。

解决方案

volatile关键字:在Java中,volatile关键字可以确保变量的修改对所有线程是立即可见的,并且禁止指令重排。当一个变量被声明为volatile时,编译器和处理器在生成和执行代码时都会遵守特定的规则,以保证volatile变量的可见性和有序性。

锁(Locks):使用锁(如synchronized关键字或显式锁如ReentrantLock)可以确保在访问共享资源时,只有一个线程能够执行临界区代码。这样可以避免因指令重排导致的数据不一致问题。

原子操作:Java的java.util.concurrent.atomic包提供了原子操作类,这些类利用底层硬件的原子操作指令来实现对单个变量的无锁并发访问。原子操作类通常利用volatile变量和CAS(Compare-And-Swap)等机制来保证操作的原子性和可见性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值