JAVA并发机制的底层实现原理

JAVA代码在编译后会变成字节码,字节码被类加载器加载到JVM中,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,JAVA中所使用的并发机制依赖于JVM的实现CPU的指令

->参考《JAVA并发编程的艺术》

1.volatile的应用

volatile是轻量级的synchronized,它只是用来保证共享变量的可见性,不能保证操纵的原子性。

【引申】–>volatile如何实现内存可见性?

  • 深入的说,通过加入内存屏障禁止重排序优化实现的。
  • 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令。
  • 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令。
1.1—volatile保证共享变量可见性

有volatile修饰的变量进行写操作的时候会多出一行汇编代码,该行代码会有一个lock指令。

volatile的两条实现原则:

①: Lock前缀指令会引起处理器缓存会写到内存(使处理器独占任何共享内存)。

②:一个处理器的缓存回写会导致其他处理器的缓存无效。

2.synchronized的实现原理和应用

⑴ synchronized实现同步的基础:

①:对于普通方法,锁是当前实例对象。

②:对于静态同步方法,锁是class对象。

③:同步方法块,锁是synchronized后面括号里的对象。

⑵ JVM规范中的实现原理

JVM基于进入和退出Monitor对象实现方法同步和代码块的同步

⑶Mark Word标记位

synchronized用到的锁是放在JAVA对象头里面的,其中有个Mark Word来存储对象的hashcode、分代年龄和锁标记位,其中锁标记位会产生变化,对应的不同的标记,我们的锁有3种:轻量级锁、重量级锁、偏向锁

⑷锁的升级与对比

从SE 1.6开始,锁一共有四种状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态。

①:偏向锁

引入原因:大多数情况下,锁仅有某一线程多次获得,为了使获得锁的代价更低而引入偏向锁。

偏向锁的设置:当某一线程访问同步块时,会在对象头和栈帧中的琐记录里存储锁偏向的线程ID,以后该线程在进入该同步块的时候,不需要再次使用CAS原子操作进行加锁和解锁,只需要简单的测试一下对象头中的Mark Word是否存在指向当前线程的偏向锁。如果测试成功,则表示获得锁,否则检测是否设置有偏向锁,如果没有,则使用CAS竞争锁,否则偏向锁指向该线程。

偏向锁的关闭:在6和7中是默认采用的,可以通过JVM参数关闭:UseBiaseLocking=false,此时程序进入轻量级锁的状态。

②:轻量级锁

加锁:线程执行同步块之前,会在线程私有的栈帧中开辟用于存储锁记录的空间,称为Displaced Mark Word。然后线程尝试将对象Mark Word的替换为指向Displaced Mark Word记录的指针,如果成功,那么当前线程获得锁,如果失败,那么使用自旋获得锁。

何为自旋?

这里写图片描述

轻量级锁解锁: 使用原子的CAS操作将Displaced Mark Word 替换回对象头,如果成功,表示没有竞争发生,否则,说明当前锁存在竞争(从上图可以看出,竞争锁的线程一直在尝试修改Mark Word,这肯定存在竞争),锁就会膨胀成重量级的锁。

因为自旋会消耗CPU,为了避免太多无用的自旋,一旦锁膨胀成重量级的锁,便不会再恢复到轻量级的锁的状态。当锁处于这个状态下,其他线程试图获取锁时就被阻塞住。当锁释放时再唤醒这些线程。此时醒来的线程就会进行一轮新的竞争。

三种锁的比较:

优点缺点使用场景
偏向锁加锁和解锁不需要额外的消耗,和执行非同步方法之间存在纳秒级的差距线程间存在锁的竞争,会带来额外的锁撤销的消耗适用于只有一个线程访问同步块的场景
轻量级锁竞争的线程不会阻塞,提高程序的响应速度自旋消耗CPU追求响应时间,同步块执行速度快
重量级锁线程竞争不使用自旋,不消耗CPU线程阻塞,响应时间慢追求吞吐量,同步块执行速度较长

3.原子操作的实现原理

⑴处理器实现原子操作的机制:

第一机制:总线锁(声言Lock信号)

第二机制共享缓存锁(修改内存地址,缓存一致性机制:阻止同时修改由2个以上的处理器缓存的内存区域数据)。

⑵JAVA实现原子操作的机制

第一个是循环CAS:JVM中的CAS操纵是利用了处理器提供的CMPXCHG指令实现的。自旋CAS的基本思路是循环进行CAS操作,直到CAS操作成功了为止。

⑶使用锁机制实现原子操作

锁机制保证只有获得锁的线程才能够操作锁定的内存区域。注意:除了偏向锁,JVM实现锁的方式都用了循环CAS操作(使用循环CAS获取锁,使用循环CAS释放锁)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值