synchronized 锁的优化过程:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁

 

一、不同锁对象的状态表示(需要了解 Java 对象头)

https://wiki.openjdk.java.net/display/HotSpot/Synchronization

Java-synchronized 中锁的状态及其转换

 

二、关于 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)中关于检测一个对象是否处于可偏向状态的源码

Java-synchronized 中锁的状态及其转换
// 返回 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));
}
View Code

相关文章: