锁的升级(Synchonized重量级转换):无锁--》偏向锁--》轻量级锁--》重量级锁

目录

线程的状态转换中锁的升级过程

三种锁的优缺点


无锁--》偏向锁--》轻量级锁--》重量级锁             这三个说的是Synchonized重量级转换

没有竞争偏向锁,轻微竞争轻量级锁,重度竞争重量级锁

线程的状态转换中锁的升级过程

就绪队列随时可能被cpu调用,阻塞队列中的线程得在加锁资源被线程释放之后通知阻塞队列,然后该线程进入就绪队列参与竞争

一个线程进入运行状态先判断所需资源有没有加锁,如果加锁进入堵塞队列,如果没有的话给他加上锁。

虽然是多线程访问一定的资源,但是不是在相同的时间段内,就不是真正的并发了。而加锁的过程很麻烦。

在没什么并发的情况下,我们就没必要加锁释放锁,这个时候用偏向锁

偏向锁:是一种简化的加锁和释放锁的过程。加偏向锁之后,当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。

偏向锁适用于几乎没有并发的时候,虽然访问一个线程,但是不是同一时间

轻量级锁:没有进入阻塞队列,仍在就绪队列而是有个死循环(CAS实现自旋锁),以非常高的频率过来查看,一看锁释放后立刻加锁。加锁的速度非常快但是会造成cpu的消耗

线程逐步增多,一个持有锁,其他全部自旋,对CPU的消耗很大。轻量级锁的缺点就是在并发高时,对cpu的损耗极大

总线的宽度为36~41位,64字节的数据往回更新需要两个批次,这两个批次的传输之间可能产生问题。

轻量级锁加锁:线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。

轻量级锁解锁时,会使用原子的CAS操作将Displaced Mark Word替换回到对象头,如果成功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。

所以当高并发时,竞争锁失败时进入阻塞队列,在就绪队列全部释放锁后,从阻塞队列挑一个执行,虽然加锁释放锁的过程麻烦,但是对cpu的损耗少,总体时间少

没有竞争偏向锁,轻微竞争轻量级锁,重度竞争重量级锁。轻微竞争的时候cpu经得起消耗,高并发时cpu经不起消耗了,就会转重量级锁(高并发时,虽然重量级锁性能不好,但是对cpu的损耗小,相比另外两个反而总体性能会变好)

三种锁的优缺点

锁的升级(Synchonized重量级转换):无锁--》偏向锁--》轻量级锁--》重量级锁_第1张图片

你可能感兴趣的:(并发编程,java)