JMM(Java Memory Model)

JMM是规范,Java Memory Model

是一组规范,需要各个JVM的实现来遵守JMM规范,以便于开发者可以利用这些规范,更方便地开发多线程程序

如果没有这样的一个JMM内存模型来规范,那么很可能经过了不同JVM的不同规则的重排序之后,导致不同的虚拟机上运行的结果不一样,那是很大的问题。

 

为啥需要JMM?

1.C语言不存在内存模型的概念

2.依赖处理器,不同处理器结果不一样

3.无法保证并发安全

4.需要一个标准,让多线程运行的结果可预期

 

重排序、可见性、原子性

1.重排序:在线程1内部的两行代码的实际执行顺序和代码在Java文件中的顺序不一致,代码指令并不是严格按照代码语句执行的,他们的顺序被改变了,它就是重排序,这里被颠倒的y=a和b=1

代码案例

提高处理速度

2.可见性:使用volatile避免可见性问题

导致可见性问题的原因:CPU有多级缓存,导致读的数据过期(高速缓存的容量比主内存小,但是速度仅次于寄存器,所以在CPU和主内存之间多了Cache层;线程间的对于共享变量的可见性问题,不是直接由多核引起的,而是由多缓存引起的;如果所有核心都只用一个缓存,那么也就不存在内存可见性问题;每个核心都会将自己需要的数据读到独占缓存中,数据修改后也是写入到缓存中,然后等待刷入到主存中。所以会导致有些核心读取的值是一个过期的值)

3.原子性:一系列的操作,要么全部执行成功,要么全部不执行,不会出现执行一半的情况,是不可分割的。

用synchronized实现原子性

 

java中原子操作有:

1.除long和double之外的基本类型(int,byte,boolean,short,char,float)的赋值操作

2.所有引用reference的赋值操作,不管是32位的机器还是64位的机器

3.java.concurrent.Atomic.*包中所有类的原子操作

 

主内存和本地内存的关系

1.所有的变量都存储在主内存中,同时每个线程也有自己独立的工作内存,工作内存中的变量内容是主内存中的拷贝

2.线程不能直接读写主内存中的变量,而是只能操作自己工作内存中的变量,然后再同步到主内存中

3.主内存是多个线程共享的,但线程之间不共享工作内存,如果线程间需要通信,必须借助主内存中转来完成

所有的共享变量存在于主内存中,每个线程有自己的本地内存,而且线程读写共享数据是通过本地内存交换的,所以才导致了可见性问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值