Java——》synchronized锁升级 本是古典 何须时尚 2024-03-03 08:00 14阅读 0赞 > 推荐链接: > [总结——》【Java】][Java] > [总结——》【Mysql】][Mysql] > [总结——》【Redis】][Redis] > [总结——》【Kafka】][Kafka] > [总结——》【Spring】][Spring] > [总结——》【SpringBoot】][SpringBoot] > [总结——》【MyBatis、MyBatis-Plus】][MyBatis_MyBatis-Plus] > [总结——》【Linux】][Linux] > [总结——》【MongoDB】][MongoDB] > [总结——》【Elasticsearch】][Elasticsearch] #### Java——》synchronized锁升级 #### * 一、无锁 * * 1、无锁 * 2、匿名偏向 * 二、偏向锁 * * 1、获取锁资源的过程(锁升级过程) * 2、为什么要有偏向锁延迟 * 3、为什么偏向锁撤销会导致启动变慢 * 4、偏向锁撤销安全点 * 5、偏向锁重入 * 6、偏向锁会降级到无锁状态吗以及如何降 * 三、轻量级锁 * 四、重量级锁 * * 1、重量级锁会降级到偏向锁或者是轻量级锁吗 * 2、如何竞争锁资源 > synchronized在jdk1.6之前,一直是重量级锁,只要线程获取锁资源失败,直接挂起线程(用户态切换到内核态),效率低,所以JDK团队在Jdk1.6将synchronized做了3方面优化:锁升级、锁消除、锁膨胀。 **锁就是对象,Java中所有对象都是锁。** <table> <thead> <tr> <th>锁</th> <th align="left">描述</th> </tr> </thead> <tbody> <tr> <td><strong>无锁/匿名偏向</strong></td> <td align="left"><strong>无锁</strong>:没有开启偏向锁(偏向锁延迟开启时间内),没有线程拿锁<br><strong>匿名偏向</strong>:开启偏向锁,没有线程拿锁,没有偏向任何线程</td> </tr> <tr> <td><strong>偏向锁</strong></td> <td align="left">只有一个线程来拿锁资源,没有竞争</td> </tr> <tr> <td><strong>轻量级锁</strong></td> <td align="left">偏向锁出现竞争时,会升级到轻量级锁(触发偏向锁撤销),以CAS的方式(自适应自旋锁)去竞争锁资源,不会让线程挂起。(LockRecord)</td> </tr> <tr> <td><strong>重量级锁</strong></td> <td align="left">直接采用MarkWord指向的ObjectMonitor以传统的方式去竞争锁资源</td> </tr> </tbody> </table> ![image.png][] ![image.png][image.png 1] ## 一、无锁 ## ### 1、无锁 ### 一般情况下,**new出来的一个对象**,是**无锁状态**。 因为偏向锁有延迟,在启动JVM的4s中,不存在偏向锁。 ### 2、匿名偏向 ### 如果关闭了偏向锁延迟的设置,new出来的对象,就是**匿名偏向**,但没有偏向任何线程。 //关闭延迟开启偏向锁 -XX:BiasedLockingStartupDelay=0 //4s之后开启偏向锁 -XX:BiasedLockingStartupDelay=4 //禁止偏向锁 -XX:-UseBiasedLocking //启用偏向锁 -XX:+UseBiasedLocking ## 二、偏向锁 ## 没有线程的竞争,只有一个线程在获取锁资源。 ### 1、获取锁资源的过程(锁升级过程) ### 当某一个线程来获取这个锁资源时,发现没有线程占用锁资源,并且锁是偏向锁,使用CAS的方式,设置对象的线程ID为当前线程,获取到锁资源,下次当前线程再次获取锁资源时,只需要判断是偏向锁,并且对象的线程ID是当前线程ID就直接获得到锁资源。如果对象的线程ID不是当前线程ID,也就是说偏向锁状态出现了锁竞争的情况,就触发锁升级,升级为轻量级锁。 ### 2、为什么要有偏向锁延迟 ### JVM在启动时,需要加载大量的.class文件到内存中,这个操作会涉及到synchronized的使用,为了避免出现**偏向锁撤销导致启动效率变慢**,所以JVM启动时,有一个延迟4s开启偏向锁的操作。 偏向锁是延迟开启的,并且在开启偏向锁之后,默认不存在无锁状态,只存在匿名偏向。 ### 3、为什么偏向锁撤销会导致启动变慢 ### 当偏向锁升级到轻量锁时,会触发**偏向锁撤销**。 (1)偏向锁撤销需要等到一个**安全点**(STW),才可以做偏向锁撤销。 (2)偏向锁撤销的**成本太高**(消耗资源) ### 4、偏向锁撤销安全点 ### * GC * 方法返回之前 * 调用某个方法之后 * 抛出异常的位置 * 循环的末尾 ### 5、偏向锁重入 ### 用到了**LockRecord**,只不过内部不会存储hashcode信息等等,在偏向锁重入时,每次都会压栈一个LockRecord,从而实现偏向锁重入。 ### 6、偏向锁会降级到无锁状态吗以及如何降 ### 会。 当偏向锁状态下,获取当前对象的hashcode值,会因为对象头空间无法存储hashcode,导致降级到无锁状态。 ## 三、轻量级锁 ## 如果出现了**多个线程的竞争**,就要升级为**轻量级锁**(有可能直接从无锁变为轻量级锁,也有可能从偏向锁升级为轻量级锁,会触发偏向锁撤销)。 轻量级锁的是**基于CAS**尝试获取锁资源,这里会用到**自适应自旋锁**,JVM会自动的根据上次CAS成功与否,决定这次自旋多少次。 * 如果成功获取到,拿着锁资源走 * 如果自旋了一定次数,没拿到锁资源,锁升级为重量级锁 ## 四、重量级锁 ## 轻量级锁CAS一段次数后,没有拿到锁资源,升级为重量级锁。线程拿不到锁,就挂起。 public static void main(String[] args) throws InterruptedException { Thread.sleep(5000); Object o = new Object(); System.out.println(ClassLayout.parseInstance(o).toPrintable()); new Thread(() -> { synchronized (o){ //t1 - 偏向锁 System.out.println("t1:" + ClassLayout.parseInstance(o).toPrintable()); } }).start(); //main - 偏向锁 - 轻量级锁CAS - 重量级锁 synchronized (o){ System.out.println("main:" + ClassLayout.parseInstance(o).toPrintable()); } } ### 1、重量级锁会降级到偏向锁或者是轻量级锁吗 ### 不会 ### 2、如何竞争锁资源 ### 直接采用MarkWord指向的**ObjectMonitor**以传统的方式去竞争锁资源 [Java]: https://blog.csdn.net/weixin_43453386/article/details/84788317 [Mysql]: https://blog.csdn.net/weixin_43453386/article/details/88667709 [Redis]: https://blog.csdn.net/weixin_43453386/article/details/127966762 [Kafka]: https://blog.csdn.net/weixin_43453386/article/details/128189472 [Spring]: https://blog.csdn.net/weixin_43453386/article/details/124900806 [SpringBoot]: https://blog.csdn.net/weixin_43453386/article/details/84788714 [MyBatis_MyBatis-Plus]: https://blog.csdn.net/weixin_43453386/article/details/84788053 [Linux]: https://blog.csdn.net/weixin_43453386/article/details/89241912 [MongoDB]: https://blog.csdn.net/weixin_43453386/article/details/84788450 [Elasticsearch]: https://blog.csdn.net/weixin_43453386/article/details/108583782 [image.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/03/349b03aa0d3e4833bbb5a1edcf59dd0f.png [image.png 1]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/03/761bc16619a7453f9dc6937dabc0e28a.png
还没有评论,来说两句吧...