抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文主要学习了多线程中有关锁的一些特性。

环境

Windows 10 企业版 LTSC 21H2
Java 1.8

1 锁升级

在JDK1.5之前,使用synchronized是操作系统级别的重量级操作。在JDK1.6之后,为了减少获得锁和释放锁所带来的性能消耗,引入了轻量级锁和偏向锁。

在Java对象头里的MarkWord中存储了synchronized用到的锁,锁升级主要依赖占用1位的偏向锁标志位和占用2位的锁标志位。

1.1 无锁

对象被实例化后,如果没有线程竞争锁,就是无锁状态。

偏向锁标志位为0,锁标志位为01。

1.2 偏向锁

同步代码一直被同一个线程访问,在后续访问时会自动获得偏向锁。

偏向锁标志位为1,锁标志位为01。

1.3 轻量锁

同步代码存在线程竞争,会升级为轻量锁,通过CAS自旋尝试获取锁。

偏向锁标志位为0,锁标志位为00。

1.4 重量锁

同步代码存在线程竞争,并且通过CAS自旋尝试超过一定次数以后,仍未能获取锁,会升级为重量锁。

偏向锁标志位为0,锁标志位为10。

2 锁消除

如果在同步代码块中锁的是局部对象,而不是共享对象,编译器就会无视同步代码块,相当于并没有对锁住的对象加锁,消除了锁的使用。

3 锁粗化

如果前后同步代码块锁住的都是同一个对象,编译器就会把代码块合并成更大的代码块,加粗加大范围,一次申请锁使用即可,避免多次的申请和释放锁,提升了性能。

评论