006-Java内存模型JMM

Java知识点总结系列目录

1. JMM

  • 概述

JMM的全称是Java Memory Model(Java内存模型),线程间通讯是通过共享内存来实现的,所以也叫共享内存模型,它是多线程和并发编程的基础。

内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节

通过该内存模型屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果,实现了跨平台

在这里插入图片描述

  • 规范

JMM规定了所有的变量都存储在主内存中。每个线程还有自己的工作内存, 线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。

  • 内存原子操作

    结合以下代码进行分析一下内存的8个原子操作

    public class JMMTest {
        private static boolean flag = false;
    
        public static void main(String[] args) {
            new Thread(()->{
                while (!flag) {
                    //wait
                }
    
                System.out.println("=======success=====");
            }, "threadB").start();
    
            //保证线程B先执行
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(()->{
                flag = true;
            }, "threadA").start();
        }
    }
    

    大致过程如下图所示
    在这里插入图片描述
    对于线程B
    1)在程序使用flag变量之前先要进行read操作,将主内存的共享变量flag传输到线程的工作内存
    2)将传输到工作内存的变量进行load操作,此时线程B中就flag=false
    3)CPU使用工作内存的变量进行use操作,对flag进行取反运算

    对于线程A
    1)在程序使用flag变量之前先要进行read操作,将主内存的共享变量flag传输到线程的工作内存
    2)将传输到工作内存的变量进行load操作,此时线程A工作内存中就flag=false
    3)CPU使用工作内存的变量进行use操作,将flag的值设置为true
    4)将CPU运算的结果赋值给工作内存的变量进行assign操作,此时线程A工作内存中flag为true

    下面我们对代码稍作修改,将flag的定义加入volatile进行修饰

    private static volatile boolean flag = false;
    

    因为flag用了volatile修饰,它将给flag带来以下两个特性
    1)发生assign操作后将工作内存的值立即写回主内存
    2)开起总线的嗅探机制,写回主内存时将其他工作内存中的该变量置位失效(MESI缓存一致性)

    此时接着上面介绍内存原子操作继续讲,对于线程A
    5)立即将flag的值写回主内存,此时将先会执行lock操作,将该内存行进行锁定,以防其他线程进行脏读
    6)然后执行store操作,将flag的值传输回主内存
    7)主内存中执行write操作,将主内存的flag值置位true
    8)最后将锁释放,执行unlock操作

    对于线程B,由于总线嗅探机制发现flag的值发生改变,线程B工作内存中的flag变量将失效,使用时需要重新从主内存读取,执行read和load操作。在执行read操作时如果发现该内存地址被锁住,则需要等到锁的释放

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值