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

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

正文


今天一起讨论一下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的运行效率,此时就会变成重量级锁,从用户态到内核态。结果就是获取锁的线程继续执行,其他的线程被挂起,等待可以执行的资源。为什么会这个样子呢,因为轻量级锁和偏向锁都是在用户态完成的,势必会进行循环执行,检测这个锁是否可以获取,线程的数目比较少还好,如果比较多,就会增加用户态的压力,这时候只能将这些竞争的线程挂起,释放用户态执行的压力。

相关文章
|
6月前
多线程并发锁的方案—原子操作
多线程并发锁的方案—原子操作
|
8天前
|
Java
无锁和偏向锁有什么区别吗
【10月更文挑战第20天】无锁和偏向锁有什么区别吗
9 0
|
5月前
|
存储 安全 算法
深入探索Java中的MarkWord与锁优化机制——无锁、偏向锁、自旋锁、重量级锁
深入探索Java中的MarkWord与锁优化机制——无锁、偏向锁、自旋锁、重量级锁
125 1
|
6月前
|
Java 编译器
多线程(锁升级, 锁消除, 锁粗化)
多线程(锁升级, 锁消除, 锁粗化)
55 1
|
安全 算法 Java
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
|
6月前
|
存储 安全 Java
12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁
12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁
72 1
12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁
|
6月前
多线程并发锁方案—自旋锁
多线程并发锁方案—自旋锁
|
6月前
|
Java 编译器 程序员
synchronized 原理(锁升级、锁消除和锁粗化)
synchronized 原理(锁升级、锁消除和锁粗化)
|
Java
加锁和释放锁的原理
当方法执行完后或者抛出异常后,都会释放锁
58 0
|
存储 Java C++
【全网最细系列】synchronized锁详解,偏向锁与锁膨胀全流程
【全网最细系列】synchronized锁详解,偏向锁与锁膨胀全流程
550 0