Java内存模型JMM(一)

JMM模型

定义:

Java内存模型(JMM)是一种抽象的概念,不是 JVM内存模型

组成:

  • 线程
  • 工作内存 —— 线程私有的一块内存空间 也称栈空间
  • 主内存 —— **共享内存区域。**所有线程都能访问
  • 总线 —— 完成主内存和工作内存之间的数据交互的桥梁
  • 执行引擎 —— CPU执行操作

JMM图

JMM存在的必要性

工作内存和主内存数据如何交互?

JMM定义了以下数据同步八大原子操作来实现

八大原子操作

指令行为位置
read主内存拷贝一份变量的数据副本主内存
load数据副本加载到工作内存主内存->工作内存
use执行引擎使用给数据副本工作内存->执行引擎
assign执行引擎赋值给数据副本执行引擎->工作内存
store数据副本传回主内存工作内存->主内存
write数据副本赋值给原变量主内存
lock主内存变量标记为线程独占主内存
unlock主内存变量取消线程独占主内存

数据交互顺序:

  • 主内存变量 read 生成数据副本
  • 数据副本 load 进工作内存
  • 执行引擎 use 数据副本
  • 执行引擎 assign 给数据副本
  • 数据副本 store 到主内存
  • 主内存数据副本 write 给原变量

数据交互中可能产生的问题

因为工作内存是线程私有的,而主内存的资源是共享的,在多线程并发的情况下,就有可能导致脏写更新覆盖】的问题

怎么解决?

首先需要了解,并发编程的三大特性

并发编程的三大特性

原子性

​ 原子性是指:**一个操作不可中断,**即使在多线程情况下,一个操作一旦开始就不会被其他线程影响。

​ Java规定**对于基本数据类型的读写操作是原子的**

可见性

​ 可见性是指:一个线程修改了某个共享变量的值,其他线程能够马上得知这个修改的值

​ 在多线程情况下,线程A修改了共享变量X的值,而还未写回主内存时,此时线程B读到共享变量X的值【仍为旧值】,这种 工作内存与主内存同步延迟现象 造成了可见性问题。

有序性

​ 因为指令重排序【性能优化】,导致在多线程情况下有可能导致指令顺序未必一致的问题

四个问题

怎么解决原子性问题?

可以通过加锁的方式来实现原子性

  • synchronized
  • Lock

加锁可以保证 任一时刻只有一个线程访问该代码

怎么解决可见性问题?

  1. volatile 关键字保证可见性

    他能保证共享变量x的值被修改后能立即被其他线程看到

  2. 加锁可以保证可见性

    因为加锁可以保证 任一时刻只有一个线程访问该代码,释放锁之前,共享变量的值被刷新回主内存

怎么解决有序性问题?

  1. volatile 关键字保证有序性

    禁止指令重排序,从而保证有序性

  2. 加锁可以保证可见性

    因为加锁可以保证 任一时刻只有一个线程访问该代码,相当于单线程环境下,自然有序

什么是指令重排序?

只要程序的最终结果与JVM顺序化情况的结果相等,那么指令的执行顺序 可以 与代码顺序不一致,此过程叫指令重排序 【为了符合CPU特性,增强性能】

指令重排序遵循as-if-serial语义happens-before原则

as-if-serial语义

不管怎么重排序,程序执行结果都不能被改变。

happens-before 原则

规则解释
程序顺序原则在一个线程内必须保证语义顺序执行 【可重排】
锁规则如果对于一个锁解锁后,再加锁,那么加锁的动作必须在解锁动作之后
volatile规则volatile变量的写,先发生于读【读最新值】
线程启动规则如果线程A在执行线程B的start()之前修改了共享变量的值,那么当线程B执行start()时,线程A对共享变量的修改对线程B可见
传递性A先于B ,B先于C 那么A必然先于C
线程终止规则线程的所有操作先于线程的终结
线程中断规则先调用线程interrupt(),再检测中断事件的发生interrupted()
对象终结规则对象的构造函数执行,结束先于finalize()方法 【GC】
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值