Java中锁的升级

synchronized

synchronized实现 同步的基 础:
对于普通同步方法,锁 是当前 对象。
对于静 同步方法, 是当前 Class 对象。
对于同步方法 Synchonized 括号里配置的 对象。

对象头

synchronized 用的 是存在 Java 头里的。如果对象是数组类型,则虚拟机用3个字宽(Word)存储对象头,如果对象是非数组类型,则用2字宽存储对象头。在32位虚拟机中,1字宽等于4字节,即32bit,如图:

Java 里的 Mark Word 里默 储对 象的 HashCode 、分代年 锁标记 位。 32 JVM 的Mark Word 的默 储结 构如下图所示
在运行期 Mark Word 里存 的数据会随着 锁标 志位的 化而 化。 Mark Word 可能 变化为 以下 4 种数据,如下图所示

锁升级

由于JDK1.6 之前,synchronized实现锁机制为重量级锁,线程的切换涉及到用户态和内核态的切换,效率较低,所以JDK1.6 提出了锁升级的概念。
了减少 锁带 来的性能消耗,引入了 偏向 级锁 ,在 Java SE 1.6中, 一共有 4 种状 级别 从低到高依次是:无 、偏向 级锁 状态和重量 级锁 几个状 会随着 争情况逐 升级,但是锁 可以升 但不能降 级。
偏向锁
当一个 线 访问 同步 并获取 锁时 ,会在 栈帧 中的 锁记录 里存 储锁 偏向的 线 ID ,以后 该线 程在 入和退出同步块时 不需要 CAS 操作来加 和解 锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁):如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。
轻量级锁
线 程在 行同步 之前, JVM 会先在当前 线 程的 栈桢 建用于存 储锁记录 的空 ,并将对 中的 Mark Word 复制到 锁记录 中, 然后 线 尝试 使用CAS将 中的 Mark Word 换为 指向 锁记录 的指 。如果成功,当前 线 ,如果失败,表示其他 线 ,当前 线 程便 尝试 使用自旋来
重量级锁

如果自旋获取锁失败,资源对象锁膨胀为重量级锁同时将锁状态修改为10。然后将该线程阻塞。Jvm恢复拥有资源锁的线程并继续执行同步代码块。因为自旋会消耗CPU了避免无用的自旋(比如线程被阻塞住了),一旦级成重量级锁,就不会再恢复到级锁。当锁处个状下,其他线试图获锁时,都会被阻塞住,当持有锁线之后会线程,被醒的线程就会行新一轮的夺锁之争。

锁升级过程是一个动态的过程,根据线程竞争的情况进行自动切换。在锁升级过程中,JVM会评估竞争情况,根据具体情况选择合适的锁类型,以提高程序的并发性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值