java偏向锁_Java的并发编程:偏向锁,轻量级锁和重量级锁 - Break易站

Java锁的种类:偏向锁,轻量级锁和重量级锁

我们在Java的并发编程:从synchronized保证线程安全的原理这篇文章中,已经说到了synchronized可以用锁来保证线程的安全问题,那么,我们这一节要说的就是锁的分类。以前是只有重量级锁这个分类,但是自从JDK6引入了偏向锁和轻量级锁之后,锁的种类就有下面三种了:

偏向锁

轻量级锁

重量级锁

Java锁存储的地方

任何对象都可以作为锁,那么锁信息又存在对象的什么地方呢?Java的锁存在对象头中,具体位置是对象头中的Mark Word。具体对象的头信息有:

Mark Word (Java的锁信息)

Class Metadata Address

Array Length

那么Java的锁信息主要存储下面这些内容:

线程id

Epoch

对象的分代年龄信息

是否是偏向锁

锁标志位

锁标志位主要就是用来分类锁的种类。

偏向锁,轻量级锁和重量级锁

为了换取性能,JVM在内置锁上做了非常多的优化。理解偏向锁、轻量级锁、重量级锁的要解决的基本问题,几种锁的分配和膨胀(升级)过程,有助于编写并优化基于锁的并发程序。

Java的偏向锁

偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁产生的性能消耗。主要有下面这些特点:

每次获取锁和释放锁会浪费资源

很多情况下,竞争锁不是由多个线程,而是由一个线程在使用。

只有一个线程在访问同步代码块的场景

当然了,如果明显存在其他线程申请锁,那么偏向锁将很快升级为轻量级锁。

Java的轻量级锁

--->a线程获得锁,会在a线程的栈帧里创建lock record(锁记录变量),让lock record的指针指向锁对象的对象头中的mark word.再让mark word 指向lock record.这就是获取了锁。

--->轻量级锁,b线程在锁竞争时,发现锁已经被a线程占用,则b线程不进入内核态,让b线程自旋,执行空循环,等待a线程释放锁。如果,完成自旋策略还是发现a线程没有释放锁,或者让c线程占用了。则b线程试图将轻量级锁升级为重量级锁。

qinglianglock-600x609.png

轻量级锁的加锁:

如果成功使用CAS将对象头重的Mark Word替换为指向锁记录的指针,则获得锁,失败则当前线程尝试使用自旋(循环等待)来获取锁。

轻量级锁的解锁:

当有另一个线程与该线程同时竞争时,锁会升级为重量级锁。为了防止继续自旋,一旦升级,将无法降级。

Java的重量级锁

重量级锁特点:

其他线程试图获取锁时,都会被阻塞,只有持有锁的线程释放锁之后才会唤醒这些线程,进行竞争。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值