ReentrantLock
历史:李二狗看到Synchronized效率太低,自己实现了一套基于AQS的锁。支持可重入,公平,非公平等特性。
Synchronized
历史:1.6之前效率低下,重量锁。
1.6之后进行了升级,追加了锁的升级过程。
偏向锁->轻量级锁->重量级锁。
效率和ReentrantLock差不多
一个图:
锁升级过程
JVM锁膨胀过程
膨胀过程:
- 新建实例: 匿名偏向锁。
- 第一个线程过来加锁,变成偏向锁。(高23位记录了对象的线程ID)
- 第二个线程来后,触发 偏向锁升级,轻量级锁。
重量锁膨胀:
- 新建实例,匿名偏向锁
- 第一个线程过来,变成偏向锁。
- 第二个线程过来,触发轻量级锁。(高30位,指向线程,栈中锁记录的指针-比偏向锁要精确)
- 轻量级锁一直被占用,第二个线程自旋无法获取。此时升级成重量级锁。 (高30位存互斥量指针)。
加锁hashcode,会变成轻量级锁的原因:
偏向锁没有hashcode,轻量级锁有个叫replace lock record。在栈帧里。
轻量级锁升级的时候 高30位记录了线程栈上锁的块,lockrecord .hashcode存在这个lockrecord。并且初始的mark word也存在了线程栈上。
hashcode存的位置
什么是Monitor?
一种同步工具,是java的一个对象。所有的java对象天生就是monitor。所有对象在新建的时候都会有一把看不见的锁。叫做内部锁,或者Monitor锁。就是Synchronized锁。MarkWord锁标记为10.其中指针指向 的地址就是Monitor对象的起始地址。在java虚拟机中(hotspot)Monitor是由ObjectMonitor实现的。源码在C++的ObjectMonitor.http文件中。