synchronized的锁升级(偏向锁,自旋锁(cas),重量级锁)

Posted nmwyqw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized的锁升级(偏向锁,自旋锁(cas),重量级锁)相关的知识,希望对你有一定的参考价值。

synchronzied是一个重量级锁

概念:什么叫重量级锁?

就是申请资源必须经过kernel(内核也叫操作系统),调用。

(里面涉及到了用户态(用户空间)和内核态(os)的交互)

技术图片

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

轻量级锁:是不经过操作系统。

cas:乐观锁(compare and swap)比较与交换(可以翻看Atomic原子类里源码)

技术图片

cas中的问题ABA

 技术图片

 

虽然,cas回成功但是也会带来一些隐患(如下连接)

https://blog.csdn.net/aigoogle/article/details/38533047

解决方法怎么

在给对象加时间戳,版本号等都可以操作

原子类

技术图片

 

 

 技术图片

 

 技术图片

 

 在c++的代码里,有一条汇编语言支持cas

技术图片

但是,这条cmpchg1不具有原子性,点进lock_if_mp(%4)里

 最终实现是lock cmpxchg 指令:表示在硬件在执行后面的指令会锁定一个北桥总线。(相当于锁定总线,但是比锁总线要轻量级)解决了下面的问题

 

 

 

技术图片

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

java对象在内存中的布局(导入工具:jol=java object layout)java对象布局

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

我们可以理解为对象存放在堆里是一块一块的,每一块都有布局:如图

 

 

技术图片

 

 所谓的对象上锁就是锁对象的头,所谓的锁升级就是了解markword的变化技术图片

 

jdk团队统计在jdk类库里一些方法的提供synchronized的方法,大部分情况下对是在一个线程里运行,如果一直是重量级锁会消耗大量资源提出优化

偏向锁:(jvm默认打开并在jvm启动后4秒启动)如stringbuffer里面的大部分方法是安全的,如果在同一个线程里运行,就会出现上面的情况,那么jdk做法是当一个线程第一的到这把锁,我们就认为这个锁偏向于它,实际的做法是把线程的放到了对象的对象头里。(偏向锁到轻量级只要由竞争就之间升级

偏向锁为什么默认在jvm启动后4秒才启动,因为,当jvm刚运行的时候,里面有很多syn的方法,如果还是由偏向锁再到自旋锁,这样会消耗大量资源。所以jvm既然知道是多线程,所以直接跳过了偏向锁,转变为自旋锁。

技术图片

 

 

让jvm延迟4秒启动,观察markword

技术图片

自旋锁:(支持锁锁重入)假如有两个线程同时,抢一把锁,这个时候,谁第一个抢到,就把它的id放在对象的markword上。这个过程是while(操作)

重量级锁:当线程竞争激烈,比如有10000个线程。这个时候如果还是自旋的话,会消耗大量的cpu,所以这个时候需要升级成重量级锁。

重量级锁和轻量级锁,最大的区别是,重量级需要经过os(操作系统),并且它还是提供队列,其中(waitset)存放等待的队列,让它们在里面排队,(entrylist)存放竞争的队列

(什么时候轻量级会升级到重量级呢)

jdk1.6之前是自旋超过10次,或者等待线程超过cpu核数的2分之一,自动升级

jdk1.6以后是jdk出来自适应自旋,它会自己判断什么时候升级。

技术图片

以上是关于synchronized的锁升级(偏向锁,自旋锁(cas),重量级锁)的主要内容,如果未能解决你的问题,请参考以下文章

Java synchronized锁升级过程简述(面试可用)

synchronized原理及1.6之后的锁升级优化

synchronized 锁升级过程

Java多线程和并发,synchronized底层原理

锁的种类

Java中锁升级的探究