java内存模型详解-可见性

目录

JVM运行时数据区

作用:用来描述一个java进程里面的内存时什么样的情况。
在这里插入图片描述

Java内存模型 vs JVM运行时数据区

相关概念:
Java语言规范:用来描述java语言的特性。
java虚拟机规范:用来约束各个虚拟机的实现。
java内存模型:对java语言的描述。
JVM运行时数据区:对Java虚拟机规范的描述。
在这里插入图片描述

初看java内存模型

作用:主要用来描述多线程程序的语义(特性),描述多线程程序的规则。
在这里插入图片描述

多线程中的问题

  1. 所见非所得
  2. 无法肉眼去检测程序的准确性
  3. 不同的平台有不同的表现
  4. 错误很难重现
    java提出规范说明如何解决这些问题,JVM去实现这些规则。

从内存结构到内存模型

在这里插入图片描述
可见性问题
导致问题:写没有写进主内存;读没有从主内存中读取。

  1. cpu高速缓存和可见性的关系:
    虽然被写入缓存,但是另外一个线程可能无法被读到,即为可见性问题。
    在这里插入图片描述
  2. 指令重排序
    指令重排导致代码结果不可预估,可能会导致可见性问题。
    在这里插入图片描述

JIT编译器

JIT编译存在指令重排。
在这里插入图片描述
在这里插入图片描述

volatile关键字

作用:可以保证可见性问题,写完之后,后续的读可以读到最新的数据。
java内存模型(Java语言)对volatile的规则描述:
在这里插入图片描述
JVM对volatile关键字的描述:
在这里插入图片描述
只会对相关的volatile变量不做重排序,而不是所有的。
最终实现是由JVM来完成的。

Shared Variables(共享变量)定义

Java语言规范描述
:广义上的堆,指java语言规范的堆,包括方法区和堆内存,而不是jvm的堆内存。
在这里插入图片描述
线程间的操作的定义
感知:一个线程写,可以被另一个线程读到,即为感知。
资源竞争和线程间操作:同时有多个线程对同一个资源进行操作,其中至少有一个是写,则存在资源竞争,出现资源竞争后这样的一个操作称之为线程间操作
在这里插入图片描述
加锁和解锁也是多个线程的操作,会影响其它线程,也属于线程间的操作。

对于同步的规则定义

在这里插入图片描述
同步即为可见。
监视器主要针对于Synchronized。
默认值防止读到乱码或其它值。
启动线程 t1.start会修改线程状态的操作,t2会感知。
最后操作 t2线程执行完后,t1线程可见。
总结:不会被缓存,不会做相应的指令重排,保证可见性。

Happens-before先行发生原则

在这里插入图片描述

final在JMM中的处理

java内存模型中对final的描述规则。
多线程环境下只有用final修饰才能看到正确的构造版本。
如果没有用final修饰,可能看到的就是默认值。
在这里插入图片描述

Word Traring字节处理

不要多线程中对字节数组进行读写操作。
在这里插入图片描述

double和long的特殊处理

虽然JVM已经实现原子操作,但是java语言规范建议
在这里插入图片描述

再看Java内存模型

总结
java内存模型和JVM内存区域是完全不同的东西,不要混淆。
java内存模型解决java多线程中存在的以上问题。
volatile主要解决读写的可见性问题,禁止缓存指令重排
staitc不保证可见性,只是将数据存在方法区,而不是存在堆中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值