存储位置: 对象头的Mark Work
// markWord.hpp
// 32 bits,32bit的MarkWord存储信息如下:
// hash:25bit --------------->| age:4bit biased_lock:1bit lock:2bit (normal object)
// JavaThread*:23bit epoch:2bit age:4bit biased_lock:1bit lock:2bit (biased object)
// 64 bits, 64bit的MarkWord存储的信息信息如下
// unused:25bit hash:31bit -->| unused_gap:1 age:4bit biased_lock:1bit lock:2bit (normal object)
// JavaThread*:54bit epoch:2bit unused_gap:1 age:4bit biased_lock:1bit lock:2bit (biased object)
// JVM底层代码定义的状态锁的值
// [ptr | 00] locked ptr points to real header on stack
// [header | 0 | 01] unlocked regular object header
// [ptr | 10] monitor inflated lock (header is wapped out)
// [ptr | 11] marked used by markSweep to mark an object
// not valid at any other time
// 当前线程持有偏向锁
// [JavaThread* | epoch | age | 1 | 01] lock is biased toward given thread
// 匿名偏向锁,说明当前线程不持有偏向锁,但是对象已被其他线程设置为偏向锁
// [0 | epoch | age | 1 | 01] lock is anonymously biased
jvm底层使用的锁
// 源码定义的锁
class BasicLock // 轻量级锁
class BasicObjectLock // 对象or监视器锁,重量级锁
synchronized细节问题说明
synchronized的enter加锁源码
// synchronizer.hpp
// This is the "slow path" version of monitor enter and exit.
// "slow path": 理解为缓慢路径,也就是jvm会通过当前方法检测对象是否处于竞争状态来确定锁的升级,以便于加快程序的性能(体现在响应时间和吞吐量)
static void enter(Handle obj, BasicLock* lock, TRAPS);
// 加锁具体实现:synchronizer.cpp
// 校验是否开启偏向锁,默认是开启偏向锁的设置
if (UseBiasedLocking) {
// 撤销偏向锁操作
if (!SafepointSynchronize::is_at_safepoint()) {
// Java线程执行存在竞争,将当前的obj的markword设置为非偏向锁状态
BiasedLocking::revoke(obj, THREAD);
} else {
// is_at_safepoint: 程序的所有Java用户线程都处于停止或者阻塞状态,除了在VM线程和本地执行的Java线程可执行
// 阻塞所有Java线程,安全撤销偏向锁
BiasedLocking::revoke_at_safepoint(obj);
}
}
markWord mark = obj->mark();
assert(!mark.has_bias_pattern(), "should not see bias pattern here");
if (mark.is_neutral()) {
// 设置为轻量级锁
lock->set_displaced_header(mark);
// CAS自旋锁,如果失败将升级为重量级别锁
if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
return;
}
} else if (mark.has_locker() &&
THREAD->is_lock_owned((address)mark.locker())) {
// 锁升级失败,也就是不需要升级锁,表示当前线程已经获取锁了
// 不需要再获取相同的锁,相当于重入锁/锁消除,直接设置对应的线程栈帧的displaced_mark_word为null
assert(lock != mark.locker(), "must not re-lock the same lock");
assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock");
lock->set_displaced_header(markWord::from_pointer(NULL));
return;
}
// unused_mark : it is only used to be stored into BasicLock as the indicator that the lock is using heavyweight monitor
// 升级为重量级锁
lock->set_displaced_header(markWord::unused_mark());
// 锁升级的原因为: inflate_cause_monitor_enter,线程发生竞争争抢锁
inflate(THREAD, obj(), inflate_cause_monitor_enter)->enter(THREAD);
synchronized偏向锁的加锁与撤销流程
synchronized锁升级流程(轻量级锁升级到重量级锁过程)
synchronized的exit源码
// synchronizer.hpp
static void exit(oop obj, BasicLock* lock, Thread* THREAD);
// 具体实现:synchronized.cpp
void ObjectSynchronizer::exit(oop object, BasicLock* lock, TRAPS) {
// 对于偏向锁的处理,撤销操作是加锁的过程,这里仅仅是对偏向锁存在的验证
// 省略对应代码 ....
// 对markword的状态进行诊断判读,没有任何其他工作,
// 省略代码 .....
// 释放轻量级锁,本质上就是一个逆向恢复markword的过程
if (mark == markWord::from_pointer(lock)) {
assert(dhw.is_neutral(), "invariant");
if (object->cas_set_mark(dhw, mark) == mark) {
return;
}
}
// 释放重量级锁,需要通过slow path的方式进行释放锁
// We have to take the slow-path of possible inflation and then exit.
inflate(THREAD, object, inflate_cause_vm_internal)->exit(true, THREAD);
}
synchronized解锁的流程
锁优化目的
优化手段
感谢花时间阅读,如果有用欢迎转发或者点个好看,谢谢!!!