首页 > 其他 > 详细

高并发——CAS、Synchronized、Volatile

时间:2021-01-18 14:38:22      阅读:51      评论:0      收藏:0      [点我收藏+]

高并发——CAS、Synchronized、Volatile

一、CAS

技术分享图片

 

 

 

Compare and Exchange 比较并交换

1. CAS在JAVA最终底层的实现:cmpxchg=cas修改变量值

 

2. CAS操作在底层上有一条对应的汇编指令(硬件级别):lock cmpxchg

 

3. 多个CPU的话前面要加lock

4. Cmpxchg指令是非原子性,加上Lock 就保证了原子性 

5. Synchronized和volatile的底层都有lock指令

 

二、Synchronized的实现

1. 对象在内存中的存储布局:

技术分享图片技术分享图片

 

java -XX:+PrintCommandLineFlags -version

技术分享图片

 

 

2.工具查看对象在内存中大小

JOL=Java Object Layout

导入依赖

<dependencies>
        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>
    </dependencies>

 

技术分享图片

 

 Markword8

Classpointer本来是8开启指针压缩变4

Instance date0

Padding4   补齐至被8整除

Object o =new Object()在内存中占16字节

 

下图可以看出,锁信息是在markword中

技术分享图片

 

 

 

 3.锁升级过程

锁升级过程:

new ——>>偏向锁——>>轻量级锁(无锁,自旋锁,自适应自锁) ——>>重量级锁

synchronized优化的过程和markword息息相关。

 

newnew出来对象,没有给它上锁。

偏向锁:;来了一个线程上去直接“贴个标签(线程ID)”,后面可能还是这个线程。(效率高,无竞争)。

轻量级锁(自旋锁):来线程竞争了,撤销偏向锁,升级轻量级锁,线程都有自己的线程栈,在自己线程栈里生成各自的对象:lockrecord抢的过程是CAS操作,看谁能将自己的lockrecord“贴上去”。用CAS操作讲markword设置为指向自己这个想成的LR的指针。

 

重量级锁:竞争加剧,有线程超过10次自旋,或者自选线程数超过CPU核数的一半,JVM自己控制。继续升级为重量级锁(向操作系统申请资源)(每一个重量级锁下面有一个队列,锁升级成功相当于进入了锁的队列,在队列里如果没轮到线程执行就不会消耗CPU,线程在wait或阻塞状态)每个线程都进入队列中“冻死”,什么时候轮到对应的线程,就将其“解冻”。

技术分享图片

 

锁消除 lock eliminate

技术分享图片

 

 我们都知道StringBuffer是线程安全的,因为它的关键方法都是被synchronized修饰,但我们看上面

这段代码,我们会发现,sb这个引用只会在add方法中使用,不可能被其他线程引用(因为是局部变

量,栈私有),因此sb是不可能共享的资源,JVM会自动消除StringBuffer对象内部的锁。

 

锁粗化 lock coarsening

技术分享图片

 

 JVM会检测到这样一连串的操作,都对同一个对象加锁(while 循环内100次执行append,没有锁

粗化的就会进行100次加锁/解锁),此时JVM就会将加锁的范围粗化到这一连串的操作的外部(比如

while虚幻体外),使得这一连串操作只需要加一次锁即可。

 

 

 

 

 

 

技术分享图片

 

高并发——CAS、Synchronized、Volatile

原文:https://www.cnblogs.com/jingge0723/p/14292004.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!