Java中synchronized锁的升级过程是什么?
synchronized锁是啥?锁其实就是一个对象,随便哪一个都可以,Java中所有的对象都是锁,换句话说,Java中所有对象都可以成为锁。
这次我们主要聊的是synchronized锁升级的套路
synchronized
会经历四个阶段:无锁状态、偏向锁、轻量级锁、重量级锁依次从耗费资源最少,性能最高,到耗费资源多,性能最差。
锁原理
先看看这些状态的锁为什么称之为锁,他们的互斥原理是啥。
偏向锁
当一个线程到达同步代码块,尝试获取锁对象的时候,会查看对象头中的MarkWord
里的线程ID,如果这里没有ID则将自己的保存进去,拿到锁。若是有,则查看是否是当前线程,如果不是,就CAS尝试改,如果是,就已经拿到了锁资源。
这里详细说说CAS尝试修改的逻辑:它会检查持有偏向锁的线程状态。首先遍历当前JVM的所有存活的线程,如果能找到偏向的线程,则说明偏向的线程还存活,此时会检查线程是否在执行同步代码块中的代码,如果是,则升级为轻量级锁,去继续进行CAS竞争锁。所以加了偏向锁之后,同时只有一个线程可以拿到锁执行同步代码块中的代码。
轻量级锁
查看对象头中的MarkWord
里的Lock Record
指针指向的是否是当前线程的虚拟机栈,如果是,拿锁执行业务,如果不是则进行CAS,尝试修改,若是修改几次都没有成功,再升级到重量级锁。
重量级锁
查看对象头中的MarkWord
里的指向的ObjectMonitor
,查看owner是否是当前线程,如果不是,扔到ObjectMonitor
里的EntryList
中排队,并挂起线程,等待被唤醒。
锁升级
无锁
一般情况下,新new出来的一个对象,暂时就是无锁状态。因为偏向锁默认是有延迟的,在启动JVM的前4s中,不存在偏向锁,但是如果关闭了偏向锁延迟的设置,new出来的对象,就会添加一个匿名偏向锁。也就是说这个对象想找一个线程去增加偏向锁,但是没有找到,称之为匿名偏向。存储的线程ID为一堆0000,也没有任何地址信息。
我们可以通过以下配置关闭偏向锁延迟。
//关闭偏向锁延迟的指令 -XX:BiasedLockingStartuoDelay=0
偏向锁
当某一个线程来获取这个锁资源时,此时会成功获取到,就会变为偏向锁,偏向锁存储线程的ID。
当偏向锁升级时,会触发偏向锁撤销,偏向锁撤销需要等到一个安全点,比如GC的时候,偏向锁撤销的成本太高,所以默认开始时,会做偏向锁延迟。若是直接有多个线程竞争,会跳过偏向锁,直接变为轻量级锁。
细说一下偏向锁撤销的过程,成本为啥高呢?当一个线程拿到偏向锁之后,会把锁的对象头的Mark Work
中的线程id指向自己,当又有一个线程来了进行争抢导致锁升级的的时候,会暂停之前拿到偏向锁的线程,然后清空Mark Work中的线程id,增加一个轻量级锁,然后再恢复暂停的线程继续执行。这也是为什么等到安全点再执行锁升级的原因,因为要暂停线程。
常见的安全点:
执行GC的时候
方法返回之前
调用某个方法之后
抛出异常的位置
一个循环的末尾
轻量级锁
当在出现了多个线程的竞争,就会升级为轻量级锁,轻量级锁的效果就是基于CAS尝试获取锁资源,这里会用到自适应自旋锁,根据上次CAS成功与否,耗费的时间,决定这次自旋多少次。
轻量级锁适用于竞争不是很激烈的场景,一个线程拿到锁,执行同步代码块,很快就处理完了。再来一个线程尝试一两次也拿到了锁,再去执行,不会让一个线程等待很久。
重量级锁
如果到了重量级锁,那就没啥说的了,如果有线程持有锁,其他想拿锁的就挂起,等待锁释放后被依次唤醒。
锁粗化&锁消除
锁粗化/锁膨胀
锁膨胀是编译Java文件的时候,JIT帮我们做的优化,它会减少锁的获取和释放次数。 比如:
while(){ synchronized(){ // 多次的获取和释放,成本太高,会被优化为下面这种 } } synchronized(){ while(){ // 拿到锁后执行循环,只加锁和释放一次 } }
锁消除
锁消除则是在一个加锁的同步代码块中,没有任何共享资源,也不存在锁竞争的情况,JIT编译时,就直接将锁的指令优化掉。 比如
synchronized(){ int a = 1; a++; //操作局部变量的逻辑 }
以上是Java中synchronized锁的升级过程是什么?的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP成为许多网站首选技术栈的原因包括其易用性、强大社区支持和广泛应用。1)易于学习和使用,适合初学者。2)拥有庞大的开发者社区,资源丰富。3)广泛应用于WordPress、Drupal等平台。4)与Web服务器紧密集成,简化开发部署。

PHP适用于Web开发和内容管理系统,Python适合数据科学、机器学习和自动化脚本。1.PHP在构建快速、可扩展的网站和应用程序方面表现出色,常用于WordPress等CMS。2.Python在数据科学和机器学习领域表现卓越,拥有丰富的库如NumPy和TensorFlow。
