当前位置:网站首页>偏向锁/轻量锁/重级锁锁锁更健康,上锁解锁到底是怎么完成实现的
偏向锁/轻量锁/重级锁锁锁更健康,上锁解锁到底是怎么完成实现的
2022-06-30 20:10:00 【澎湖Java架构师】
轻量级锁升级重量级锁
- 只有一个线程抢夺时JVM上偏向锁
- 在出现一个线程时就是轻量级锁。轻量级锁通过CAS进行上锁。失败则会发生自旋
- 当自旋大一定程度或者,此时又出现一个线程上锁,此时会切换成重量级锁。
class Heavy{ } public class HeavyLock
{
public static void main(String[] args) throws InterruptedException
{
Heavy heavy = new Heavy();
final Thread t1 = new Thread(new Runnable()
{
@SneakyThrows
@Override
public void run()
{
synchronized (heavy)
{
System.out.println("t1:"+ClassLayout.parseInstance(heavy).toPrintable());
}
TimeUnit.SECONDS.sleep(1000000);
}
});
final Thread t2 = new Thread(new Runnable()
{
@SneakyThrows
@Override
public void run()
{
synchronized (heavy)
{
System.out.println("t2"+ClassLayout.parseInstance(heavy).toPrintable());
}
TimeUnit.SECONDS.sleep(1000000);
}
});
final Thread t3 = new Thread(new Runnable()
{
@SneakyThrows
@Override
public void run()
{
synchronized (heavy)
{
System.out.println("t3"+ClassLayout.parseInstance(heavy).toPrintable());
}
TimeUnit.SECONDS.sleep(1000000);
}
});
t1.start();
TimeUnit.SECONDS.sleep(2);
t2.start();
t3.start();
TimeUnit.SECONDS.sleep(5);
System.out.println(ClassLayout.parseInstance(heavy).toPrintable());
}
}
- 我们能够发现,在出现两个线程进行轻量级锁争抢的时候会切换成重量级锁。

都是重量级锁的同时,我发现其他信息是固定的,这个也和我们在内存布局中一样,这里指向的是锁指针,对应的是C++中ObjectMonitor对象指针。重量级指针内部有一个队列就是将没抢上的线程挂起用的。所以这里不会变化。这里注意和线程id进行区分
- 重量级锁用完之后就会释放掉成无锁状态。

锁操作
- 上面我们分别介绍了偏向锁,轻量级锁,重量级锁的定义及场景切换。这里我们稍微总结下三种锁使用场景
- 偏向锁在JVM开启偏向条件下,默认是偏向锁
- 当有另外一个线程再次对对象进行加锁时,不管有没有发生竞争都是轻量级锁。只不过发生竞争时会通过CAS抢占,CAS一定次数还是失败则升级重量级锁。而偏向锁切换到轻量级锁的过程是先撤销偏向锁在上轻量级锁
- 当有两个及以上的时候发生竞争就会切换成重量级锁。切换之前会有一个线程通过自旋等待。默认是10次。这是不固定的,因为有自适应自旋锁的存在
- 除了锁之间的关系,我们还需要掌握下各个锁的原理,上锁解锁的全过程
- 偏向锁 上锁 首先我们检测下状态位是否是101。如果是在看下当前markword存储的threadId是否是当前线程。如果是当前线程则可以执行当前代码块 如果不是当前线程,则通过CAS写入当前线程;如果写入成功则说明偏向锁上锁成功,继续执行当前代码块 如果CAS写入失败,则说明有资源抢占。偏向锁升级成轻量级锁。

### 解锁- 上面的代码案列中,我也有所提到偏向锁是不会主动释放的。因为我们在还没加锁的时候默认就是偏向锁。只有发生竞争了升级轻量级锁的时候才会撤销偏向锁。- 所以说偏向锁的解锁就是不操作。我们这里主要说下在升级轻量级锁是关于偏向锁的撤销的逻辑

## 轻量级锁### 上锁- 轻量级锁上锁过程需要借助一个`Lock Record` ; 他是存储在线程栈帧中的一块内存地址。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mc7pHsa9-1656577825850)(https://upload-images.jianshu.io/upload_images/28037261-93f03f9e95b44e93.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
- 因为偏向锁不需要释放,他的可重入式锁就是不做任何操作。但是在轻量级锁中涉及到释放锁。那么轻量级锁如何体现可重入式呢?;- 在上图中如果是无锁或者偏向锁会在线程栈中开辟LockRecord来存储markword的地址叫做`Displaced MardWord`- 但是在已经是偏向锁的条件分支里,我没有体现可重入式的概念。在这条分支线里实际上是检测到markword中指向的是当前栈帧的时候JVM还是会开辟一个`Lock Record`,也不会写回到markword中。`LockRecord`不会存储原本markword的内容。此时的`LockRecord`本身就是一个计数器的功能。在释放重入式锁的时候也只是删除`LockRecord`而不会去操作markword。- 为什么JVM这样设计呢?因为这样就避免了每次轻量级锁的开销### 解锁- 对于轻量级锁,其性能提升的依据是“对于绝大部分的锁,在整个生命周期内都是不会存在竞争的”,如果打破这个依据则除了互斥的开销外,还有额外的CAS操作,因此在有多线程竞争的情况下,轻量级锁比重量级锁更慢;

总结
- synchronized作为被人诟病的一个设计,在JDK1.6之后真的改版了,不要在拿之前的眼光看待他了。毕竟偏向锁和轻量级锁的引入已经将性能提升了很多了。
- 偏向锁默认进行,节省调度时间
- 轻量级锁通过CAS完成等待,省调线程挂起,唤醒等操作
- 重量级将线程串行化,保障了线程之间的并发
- 三种状态锁循序渐进给我们适配不同程度的并发需求

原
边栏推荐
- By analyzing more than 7million R & D needs, it is found that these eight programming languages are the most needed by the industry
- Jerry's touch key recognition process [chapter]
- AVL平衡二叉树(一) - 概念与C语言实现
- 数据库 OLAP、OLTP是什么?相同和不同?适用场景
- Lvalue reference and lvalue reference
- SQL必需掌握的100个重要知识点:创建和操纵表
- Great God detailed open source Buff gain Introduction 丨 Live
- Introduction to neural network (Part 1)
- Based on the open source stream batch integrated data synchronization engine Chunjun data restore DDL parsing module actual combat sharing
- 北京大学ACM Problems 1000:A+B Problem
猜你喜欢

obsidian配合hugo的使用,让markdown本地编辑软件与在线化无缝衔接

Tensorflow2.4 implementation of repvgg

为什么vscode用久了电脑速度变慢?

Study on lumiprobe modified triphosphate biotin-11-utp

PHP obtains opcode and C source code

maya房子建模

To eliminate bugs, developers must know several bug exploration and testing artifacts.

Lumiprobe染料酰肼丨BDP FL 酰肼方案

杰理之触摸按键识别流程【篇】

Golang应用 ━━ 安装、配置与使用hugo博客系统
随机推荐
Mistakes the project manager should not make
Encoding type of Perl conversion file
Description of the latest RTSP address rules for Hikvision camera, NVR, streaming media server, playback and streaming [easy to understand]
What bank card do you need to open an account online? In addition, is it safe to open an account online now?
网上炒股开户安全嘛!?
jfinal中如何使用过滤器监控Druid监听SQL执行?
哈夫曼樹(一)基本概念與C語言實現
Scene 299
Basic components of STL
Playwright - scroll bar operation
杰理之触摸按键识别流程【篇】
originpro 2021 附安装教程
Jerry's determination of detection sensitivity level [chapter]
QT qstringlist usage
杰理之关于长按复位【篇】
To eliminate bugs, developers must know several bug exploration and testing artifacts.
杰理之关于长按开机检测抬起问题【篇】
好高的佣金,《新程序员》合伙人计划来袭,人人皆可参与
Game 81 biweekly
最新海康摄像机、NVR、流媒体服务器、回放取流RTSP地址规则说明[通俗易懂]