600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 《Java并发编程的艺术》之synchronized的底层实现原理

《Java并发编程的艺术》之synchronized的底层实现原理

时间:2021-07-25 03:37:42

相关推荐

《Java并发编程的艺术》之synchronized的底层实现原理

在学习锁优化时,对象头(Mark Word)是必不可缺的一环,因为synchronized用的锁是存在对象头里的。32位的虚拟机上对象头占64位(8字节),64位的虚拟机上对象头占128位(16字节)[^objectHead];而不同的类型,对象头的布局不太一样:

数组类型:Mark Word、Class Metadata Address、Array Length普通类型:Mark Word、Class Metadata Address

Mark Word表示对象的HashCode或锁信息

Class Metadata Address表示对象的数据类型在方法区对应的地址

Array Length表示数组的长度(只在对象是数组的情况下才会存在)

对象头的默认表示应该如下所示

具体的对象内存布局看这篇文章

而根据JVM的设置1,具体分配时又会有不同的情况,如下所示

当关闭了偏向锁的设置,那么就会走左边的流程;反之则走右边的流程。

偏向锁

由于大多数情况下,锁大多都不处于多线程竞争状态,而且总是由同一个线程获取,所以JVM在1.6之后加入了偏向锁轻量锁,如今总共由4种锁状态:无状态锁偏向锁轻量锁重量锁。随着线程竞争的提升,锁会逐渐升级(无法降级)。

偏向锁在没有竞争的情况下可以提高同步的性能,这方面主要体现在偏向锁只需要进行一次CAS而轻量锁需要两次。它是一个需要权衡利弊的选择,它不是在任何情况下都对程序有利的。如果竞争很多,那么撤销偏向锁的过程就会成为性能瓶颈。

当偏向锁可用时,初始化的对象头分配如下所示

加锁过程

当对象头的isBiased为1时且锁状态为01时,偏向锁可用,继续后面的流程判断目标对象头是否包含本线程ID,如果没有,则直接CAS往对象头里写入本线程ID。到这一步加锁就结束了

锁撤销

由于偏向锁使用了一种直到竞争发生时才会释放的机制,所以当其他线程竞争偏向锁时,持有偏向锁的线程才会去释放锁。

等待原持有偏向锁的线程(后文简称原线程)运行至全局安全点(safe point)暂停原线程检查原线程的线程状态,如果退出了同步代码块,则重偏向;反之升级为轻量锁恢复原线程

轻量锁

加锁过程

注意:轻量锁会一直保持,唤醒总是发生在轻量锁解锁的时候,因为加锁的时候已经成功CAS操作;而CAS失败的线程,会立即锁膨胀,并阻塞等待唤醒。

第一次进入同步块,开辟一个叫做Lock Record的空间用于存储锁记录

将对象头中的Mark Word 复制到 当前线程栈中尝试用CAS将Mark Word替换为指向Lock Record的指针第三步操作成功,则将Mark Word设置为00状态,标识轻量锁然后执行同步体第三部操作失败,进入自旋获取锁自旋获取锁的失败次数到达阈值,膨胀锁,修改为重量级锁(状态改为10)线程阻塞

锁释放过程

尝试CAS将Lock Record的Owner复制回Mark Word如果CAS操作成功,则表示没有竞争发生;否则看步骤3释放锁并唤醒等待的线程

总结

本章是对synchronized在JVM里的各种等级及升级的流程进行了讲解,其中主要是通过控制对象头的一些状态来控制锁的等级。偏向锁通过标记Thread ID来表示,当前对象已经被对应线程占用;轻量锁则替换Mark Word为Lock Record 地址来表示当前对象被对应线程占用。无论是哪种锁,在不同的场景下有不同的需求,可以参考以下表格做出选择

偏向锁:

优点:加锁和解锁不需要额外消耗,和执行非同步方法相比,仅存在纳秒级的差距缺点:如果线程间存在竞争,会带来额外开销(偏向锁的撤销)适用场景: 适用于只有一个线程访问同步块的场景

轻量锁:

优点: 竞争的线程不会造成阻塞,提高了程序的响应速度缺点: 如果始终得不到锁,使用自旋会消耗CPU适用场景: 追求相应实践,同步块执行速度非常快

重量锁:

优点: 线程竞争不使用自选,不会消耗CPU缺点: 线程阻塞,响应时间缓慢适用场景: 追求吞吐量,同步块执行速度较慢

这个是网上找到的关于锁撤销、膨胀等操作的总流程

关于偏向锁的相关JVM设置:-XXBiasedLockingStartupDelay=0表示启动程序几秒钟后激活偏向锁-XXUseBiasedLocking=false表示关闭偏向锁(确定会发生竞争时可以这么设置)↩

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。