synchronized 锁的优化过程:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁
一、不同锁对象的状态表示(需要了解 Java 对象头)
https://wiki.openjdk.java.net/display/HotSpot/Synchronization
二、关于 Lock Record(锁记录)
https://www.jianshu.com/p/fd780ef7a2e8
当字节码解释器执行 monitorenter 字节码轻量级锁锁住一个对象时,就会在获取锁的线程的栈上显式或者隐式分配一个 Lock Record 空间。
三、偏向锁
https://www.cnblogs.com/javaminer/p/3892288.html
在 JDK 1.6 中引入,默认启用,且会延迟启动,关闭延迟:-XX:BiasedLockingStartupDelay=0,关闭偏向锁:-XX:-UseBiasedLocking=false,默认会进入轻量级锁。
为了消除数据在无竞争(大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得)情况下的同步原语,提高程序的运行性能(消除这个线程锁重入(CAS)的开销)。
1.获取锁(bytecodeInterpreter.cpp 中的 CASE(_monitorenter) 方法,其中调用了 interpreterRuntime.cpp 中的 monitorenter 方法):
OpenJDK8 的 HotSpot 源码(markOop.hpp)中关于检测一个对象是否处于可偏向状态的源码
// 返回 true 时代表 markword 的可偏向标志 bit 位为 1 ,且对象头末尾标志为 01。 bool has_bias_pattern() const { return (mask_bits(value(), biased_lock_mask_in_place) == biased_lock_pattern); } // 返回 NULL 时代表对象 Mark Word 中 bit field 域存储的 Thread Id 为空。 JavaThread* biased_locker() const { assert(has_bias_pattern(), "should not call this otherwise"); return (JavaThread*) ((intptr_t) (mask_bits(value(), ~(biased_lock_mask_in_place | age_mask_in_place | epoch_mask_in_place)))); } // 检测对象是否处于可偏向状态 bool is_biased_anonymously() const { return (has_bias_pattern() && (biased_locker() == NULL)); }