JAVA多线程-JMM内存模型

JMM内存模型

JMM内存简单介绍

java多线程内存模型跟CPU缓存模型类似,是基于CPU缓存模型来建立的,Java线程内存模型是标准化的吗,屏蔽掉了底层不同计算机的区别
相关理解:

1. 主内存中的共享变量会复制到每个线程中
2. 每个线程在各自的工作内存中读取、修改共享变量
3. 线程之间是隔离的,共享变量不可见

在这里插入图片描述

Volatile可见性

Volatile只能实现线程间共享变量的可见性,不代表原子性

代码解释

public class VolatileVisibilityTest {

    private static boolean initFlag =false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            System.out.println("waiting data....");
            while (!initFlag){
            }
            System.out.println("+++++++++++++++++success");
        }).start();

        Thread.sleep(2000);

        new Thread(()->{
            prepareData();
        }).start();
    }

    public static void prepareData(){
        System.out.println("prepareData start");
        initFlag = true;
        System.out.println("prepareData end>>>>>>>");
    }

}

运行结果
线程1还在执行,其实就是代表线程1中的变量仍是false,线程2中对全局变量initFlag的变更并未同步到线程2中。

在这里插入图片描述

在全局变量中使用volatile关键字,线程2修改对全局变量initFlag的变更,线程1能够得到全局变量InitFlag的最新值。

在这里插入图片描述

Volatile缓存可见性实现原理
底层实现主要通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并回写到主内存
IA-32和Intel 64架构软件开发手册对lock指令的解释:

  • 会将当前处理器缓存行的数据立即写回到系统内存
  • 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效(MESI协议)
  • 提供内存屏障功能,使lock前后指令不能重排

指令 重排序与内存屏障:

  • 并发编程三大特性:可见性、有序性、原子性
  • volatile保证可见性与有序性,但是不保证原子性,保证原子性需要借助synchronize这样的锁机制
  • 指令重排序:在不影响单线程程序执行结果的前提下,计算机为了最大限度的发挥机器性能,会对机器指令重排序优化
  • 重排序会遵循as-if-serial与happens-before原则

JMM原子操作

在这里插入图片描述

  • read(读取):从主内存读取数据
  • load(载入):将住内存读取到的数据写入工作内存
  • use(使用) :从工作内存读取数据来计算
  • assign(赋值):将计算好的值重新赋值到工作内存中
  • store(存储):将工作内存数据写入到主内存中
  • write(写入):将stroe过去的变量赋值给主内存中的变量
  • lock(锁定):将主内存变量加锁,标识为线程独占标识
  • unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值