内存可见性和happens-before原则

java-内存可见性

1.什么是内存可见性?

首先我们看下面这张图
在这里插入图片描述
java的运行机制来说,会为每个线程创建一个栈,线程运行的时候就会优先读取自己的工作内存内部的数据。然后在线程执行之后把数据在写会到主内存里面。但是多线程的条件下,可能会出现上一个线程还没有执行完的情况下,这个线程就要操作这个数据了,这个时候就会出现本线程去内存读到的数据和上一个线程内部的数据是不一致的。那么该如何保证一个数据在多线程之间是相同的呢?这就是内存可见性。

2.描述内存可见性的规则 happens-before 规则

简单来说就是如何A操作的结果是对B操作可见的,那么就必然存在A happens-before B的关系。注意他指的不是运行时间的先后而是可见性的先后顺序。java为了描述这种内存可见性的规则就提出了happens-before规则。

3.java里面一些天然存在的happens-before关系

程序次序原则: 在一个线程内,代码按照顺序执行
管程锁定规则: 在同一个monitor上,unlock操作时间上先行发生于后面的lock操作
volatile变量规则: 对一个volatile变量的写操作先于读操作
线程启动原则: Thread的start()先于该线程的任何操作
线程终止原则: Thread的所有操作都先于线程的终止检测。可以通过Thread.join()和Thread.isAlive()的返回值检测线程是否已终止
线程终断规则: 线程的interrupt()方法先于中断线程检测到中断事件的发生,即可以使用interrupted()方法检测到线程是否被中断了。
对象终结原则: 对象构造函数执行完毕先于finilized()方法
传递性: A先于B,B先于C。可以推断出A先于C

4.java主内存和工作内存交互的8个原子操作。

1.lock 将主内存的变量锁住。
2.unlock 主内存的变量解锁,其他线程可以获取这个变量
3.read 把主内存的变量读到写到工作内存里面
4.load 把read读取到的值存在本地的副本里面
5.usage 把本地变量的副本交给cpu执行
6.assign 把返回的结果复制给本地副本
7.store 把本地副本的值写到主内存
8.write 把主内存的值复制给主内存的变量
那么从jvm的层面来说就可以通过read和store这两个原子操作来保证内存可见性。就是读之前必须先执行read和load操作,写之后必须先执行store和write。
也就是所有的写必须happens-before读。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值