JAVA并发编程(六)锁补充

本文详细解析了Synchronized锁的三种形式,包括修饰普通方法、静态方法和代码块的锁机制。介绍了Synchronized锁在JVM中的实现原理,以及锁对象在对象头中的存储方式。探讨了锁升级的概念,包括无锁、偏向锁、轻量级锁和重量级锁的状态转换,解释了每种锁的适用场景和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Synchronized锁的三种形式:
Synchronized修饰普通同步方法,锁的是调用当前方法的实例对象。
Synchronized修饰静态同步方法,锁的是当前类的class对象。
Synchnonized修饰同步代码块,锁的是Synchronized后面括号里配置的对象。

2.Synchronized在JVM里面怎么实现?
Synchronized锁是基于进入和退出monitor对象来实现方法和代码块同步的。通过monitorentry和monitorexit这两个指令来实现的。在同步开始位置插入monitorentry指令,在同步结束的位置或者异常出现的位置插入monitorexit指令。任何对象都有一个monitor阙值,当这个对象的monitor被持有后,它将处于锁定状态。

3.Synchronized锁对象是存在哪里的哪?
存在锁对象的对象头中,称为MarkWord。
在这里插入图片描述
4.锁升级
锁的4中状态:无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态。

为什么要引入偏向锁?
大多数时候是不存在锁的竞争的,常常是一个线程多次获得同一个锁,为了减少每次竞争锁的代价,引入偏向锁。

偏向锁的升级?
当线程1访问代码块并获取锁对象时,会在java对象头和栈帧中记录偏向的锁的threadID。因为偏向锁不会主动释放,所以当线程1在此想获取锁的时候,返现threadID一致,则无需使用CAS来加锁,解锁。
如果不一致,线程2需要竞争锁,偏向锁不会主动释放里面还是存储线程1的threadID。如果线程1 没有存活,那么锁对象被重置为无锁状态,其他线程竞争并将其设置为偏向锁。
如果线程1 还存活,那么查看线程1是否需要持有锁,如果需要,升级为轻量级锁。如果不需要设置为无锁状态,重新偏向。

偏向锁默认开启。

为什么要引入轻量级锁?
轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景,为了避免阻塞线程让CPU从用户态转到内核态和代价,干脆不阻塞线程,直接让它自旋等待锁释放。

轻量级锁的升级?
线程1获取轻量级锁时会先把锁对象的对象头复制到自己的锁记录空间,然后使用CAS替换对象头的内容。
如果线程1复制对象头的同时,线程2 也准备获取锁,但是线程2在CAS的时候失败,自旋,等待线程1释放锁。

如果自旋到了次数线程1还没有释放锁,或者线程1在执行,线程2在自旋等待,这时3有来竞争,这个轻量级锁会膨胀为重量级锁,重量级锁把所有拥有锁的线程都阻塞,防止CPU空转。

几种锁的优缺点?
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值