第二章 java并发机制的底层实现原理

序言

java 代码在编译后会变成java字节码,字节码被类加载器加载到jvm里,jvm执行字节码,最终需要转化为汇编指令在cpu上执行,java中所使用的并发机制依赖于jvm的实现和cpu的指令,本章我们将深入底层一起探索java并发机制的底层实现原理

volatile的应用

volatile 是轻量级的synchronized,它在多处理器开发中保证了共享变量的可见性和有序性,可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值,它比synchronized执行成本更低,没有上下文切换与调度

  • 共享变量可见性实现原理
    使用缓存锁,对进行操作缓存进行锁定,操作完之后,再写到内存,这是其他处理器的缓存会变为无效,下次访问内存,会重新读取最新的值
  • 共享变量有序性
    在 JVM 底层 volatile 是采用“内存屏障”来实现的。带有volatile关键字时,会多出一个lock前缀指令,lock前缀指令实际上相当于一个内存屏障,来实现指令有序性(这个后面章节会详细讲解

synchronized的实现原理与应用

synchronized在并发编程中,应该说是元老级人物,很多人也称呼它为重量级锁,但在java1.6中进行了优化,引入偏向锁、轻量级锁

  • 底层原理
    monitorenter 指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束和异常处,jvm要保证每个monitorenter必须有对应的monitorexit与之配对,任何对象都有一个monitor关联,当且一个monitor被持有后,它将处于锁定状态,线程执行到monitorenter指令是,将会尝试获取对象锁对应monitor的所有权,即尝试获取锁。

  • java对象头
    synchronized用的锁是存在java对象头里面,对象头里面的Mark word 存储对象的hashcode 、分代年龄和锁标记位
    在这里插入图片描述

  • 锁的升级

大多数情况,锁不仅不存在多线程竞争,总是由同一个线程获取,这时获得锁就是偏向锁。
如果遇到线程的竞争,偏向锁就会释放,变为轻量级锁,当出现有自旋,长时间获取不到,就变为重量级锁

原子操作的实现与原理

java 是通过CAS方式实现原子操作
CAS:就是循环比较期望值与旧值,是否相等,相等则进行替换,不相等就一直循环尝试替换。

  • 注意

ABA问题:在cas方式操作值的时候,有可能出现,线程A与线程B,线程A对变量i=100进行修改200,再修改为100,那么线程B再修改A时发现,还是原来100,就会进行修改,这时就会出现了ABA问题
案例:假设你有存款1000元,你去银行转账500,转账成功了,但不小心又点一次次转账的之前,有人给你转了500,因为发现存款是1000,没有扣500,所以第二次误点转账也会成功(可能此案例不符合生活场景)。
为了解决这问题,每次转账都加一个版本号来区分是否原来的金额。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫果冻

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值