锁消除、锁粗化、锁升级区别与联系

简介: 锁消除、锁粗化、锁升级区别与联系

正文


今天一起讨论一下java对象里面锁的问题。本文按照锁消除、锁粗化、锁升级依次展开讨论。


锁消除问题


锁消除,顾名思义,但是它是如何消除的呢?有什么约束条件嘛?才可以达到一个对象可以抛开自己的锁,在多线程并发的情况下,可以正确的得到想要的结果。正如下面的代码所示:

39.png

上面的代码实现了一个简单的功能,实现从0到99返回一个简单的字符串。观察仔细的人,可以发现,这里采用的是StringBuffer进行操作字符串的。众所周知,这里面的方法都是采用synchronized修饰的同步方法。换一句话说,每条用一次方法,都会对monitor进行加一和减一,是不是很麻烦?为了消除麻烦,这里JVM进行了优化,如果局部变量的对象,加锁和去掉锁执行的结果是一样的,在JVM执行的时候,就可以对局部变量对象不需要加锁就可以执行。这样的一个过程就是JVM锁消除的过程。


锁租化问题


锁租化,按照名字来讲,也就是扩大了一个对象的锁的范围。但是如何地扩大呢?有什么要求呢?JVM是怎么处理的呢?上代码如下:

38.png

锁粗化与锁消除类似,但是有一点不同的是,这里面锁的对象从局部变量变化成了全局变量,所有的线程都可以共享、一起使用。换一句话说,不加锁肯定是不行的,但是JVM还是有优化的办法的。在上面的方法中,调用了多次的append方法,但是每一次的调用都需要加锁和释放锁,在多线程并发的场景,线程的操作会频繁的从用户态到内核态的调用,很影响JVM的运行效率。JVM为了提升代码的运行性能,针对这样的场景进行了优化,也就是将红色框内的代码,进行统一的加锁和释放锁,而且是一次。这样就避免了频繁用户态到内核态的状态转换。似乎,锁的粒度变粗了,所以这也就是锁粗化的意思啦!


锁升级问题


锁升级的过程也是针对JVM运行用户的代码进行的优化。synchronized是一个重量级锁,他会操作用户态到内核态。但是这种操作有一些场景往往是没有必要的,也就是说,想要操作用户态到内核态,也是有条件的,逐渐变化的。在昨天的文章中,Mark Word区域记录了某一个对象的锁的信息,比较关键的是偏向锁、锁信息。一个对象的锁升级的过程如下:

37.png

当某一个用户线程,获取到一个加锁的对象,并且没有其他的用户线程竞争的时候,完全可以不需要加锁进行执行。但是这个时候,第二个用户线程过来了,请求相同的锁对象,这个时候所信息会设置偏向锁,指向第一个获取用户线程。如果,用户线程超过了3个,并且竞争很激烈,这时候,会启用lock表示位,变化为轻量级锁。无论是偏向锁、轻量级锁都是在用户态完成的。如果竞争了很多次,而且用户线程越来越多,这时候会严重影响用户线程的有效执行、JVM的运行效率,此时就会变成重量级锁,从用户态到内核态。结果就是获取锁的线程继续执行,其他的线程被挂起,等待可以执行的资源。为什么会这个样子呢,因为轻量级锁和偏向锁都是在用户态完成的,势必会进行循环执行,检测这个锁是否可以获取,线程的数目比较少还好,如果比较多,就会增加用户态的压力,这时候只能将这些竞争的线程挂起,释放用户态执行的压力。

相关文章
|
缓存 算法 安全
Spring 为啥默认把bean设计成单例的?这篇讲的明明白白的
Spring 为啥默认把bean设计成单例的?这篇讲的明明白白的
221 0
|
Linux iOS开发 MacOS
PowerShell命令行输出和添加系统环境变量
主要介绍使用PowerShell命令如何查看、修改和删除系统环境变量,对于需要操作添加PATH环境变量非常实用 。由于 Powershell 的跨平台,其环境变量修改可以在linux、macos...
4782 0
PowerShell命令行输出和添加系统环境变量
|
Java Nacos Docker
Docker安装Seata分布式事务
Docker安装Seata分布式事务
Docker安装Seata分布式事务
|
6月前
|
传感器 人工智能 搜索推荐
智能硬件交互有什么发展趋势?
随着国内全网AI平台智能体数量突破千万,这些“数字人”虽功能强大,却大多困于云端,商业化比例低。同时,国内智能硬件市场同质化严重,难以满足用户长期需求。本文探讨了哪些AI智能体适合硬件实体化,并提出了四大创新方向:深度交互与情感陪伴型、特定场景解决方案型、环境感知与自主决策型。通过多模态交互、端侧专用模型、核心场景极致体验及持续服务模式,智能硬件可从同质化中脱颖而出。尽管挑战重重,但将AI“灵魂”与硬件“肉身”结合,是AI产业成熟的重要趋势。
203 2
|
消息中间件 测试技术 领域建模
DDD - 一文读懂DDD领域驱动设计
DDD - 一文读懂DDD领域驱动设计
44169 6
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
371 1
|
Java Maven
Idea下运行Maven项目时provide包没有依赖导致类找不到
Idea下运行Maven项目时provide包没有依赖导致类找不到
413 0
CountDownLatch用法、详解
CountDownLatch用法、详解
|
XML 数据格式 程序员
|
中间件 关系型数据库 MySQL
史上最详细Docker安装Mycat中间件 | 实现主从的读写分离
史上最详细Docker安装Mycat中间件 | 实现主从的读写分离
996 2