前提知识点:
无锁001
偏向锁101
轻量锁00
重量锁10
synchronized对应c++执行逻辑
case got_monitors: {
// continue locking now that we have a monitor to use
// we expect to find newly allocated monitor at the "top" of the monitor stack.
oop lockee = STACK_OBJECT(-1);
VERIFY_OOP(lockee);
// derefing's lockee ought to provoke implicit null check
// find a free monitor
// 在线程栈中创建lock record
BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor");
// 获取锁对象
entry->set_obj(lockee);
bool success = false;
uintptr_t epoch_mask_in_place = markWord::epoch_mask_in_place;
markWord mark = lockee->mark();
intptr_t hash = (intptr_t) markWord::no_hash;
// implies UseBiasedLocking
// JVM是否开启偏向模式
if (mark.has_bias_pattern()) {
// JVM开启偏向模式
uintptr_t thread_ident;
uintptr_t anticipated_bias_locking_value;
thread_ident = (uintptr_t)istate->thread();
anticipated_bias_locking_value =
((lockee->klass()->prototype_header().value() | thread_ident) ^ mark.value()) &
~(markWord::age_mask_in_place);
// 偏向锁是否偏向自己
if (anticipated_bias_locking_value == 0) {
// 偏向锁偏向自己,获取cpu执行
// already biased towards this thread, nothing to do
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::biased_lock_entry_count_addr())++;
}
success = true;
}
// 偏向锁是否被禁用
else if ((anticipated_bias_locking_value & markWord::biased_lock_mask_in_place) != 0) {
// 偏向锁被禁用(偏向锁锁撤销达到40次+)
// try revoke bias
// 获取类中的不可的偏向锁001
markWord header = lockee->klass()->prototype_header();
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
// cas 更新锁对象状态为无锁001,成功或者失败都走轻量锁模式
if (lockee->cas_set_mark(header, mark) == mark) {
if (PrintBiasedLockingStatistics) {
(*BiasedLocking::revoked_lock_entry_count_addr())++;
}
}
}
// 锁对象的epoch值是否过期(偏向锁撤销达到20次+)
else if ((anticipated_bias_locking_value & epoch_mask_in_place) !=0) {
// 过期,锁撤销大于20次,执行批量重偏向
// new 偏向当前线程的mark word
// try rebias
markWord new_header( (intptr_t) lockee->klass()->prototype_header().value() | thread_ident);
if (hash != markWord::no_hash) {
new_header = new_header.copy_set_hash(hash);
}
// cas 更新锁对象为偏向当前线程的mark word
if (lockee->cas_set_mark(new_header, mark) == mark) {
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::rebiased_lock_entry_count_addr())++;
}
} else {
// 执行锁撤销,轻量锁膨胀过程
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
}
// 匿名偏向锁,偏向其它线程偏向锁
else {
// try to bias towards thread in case object is anonymously biased
// new 匿名偏向锁101
markWord header(mark.value() & (markWord::biased_lock_mask_in_place |
markWord::age_mask_in_place | epoch_mask_in_place));
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
markWord new_header(header.value() | thread_ident);
// debugging hint
DEBUG_ONLY(entry->lock()->set_displaced_header(markWord((uintptr_t) 0xdeaddead));)
// 是否是匿名偏向锁加锁
if (lockee->cas_set_mark(new_header, header) == header) {
// 是匿名偏向锁加锁
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
}
} else {
// 是偏向其它线程偏向锁,执行锁撤销,轻量锁膨胀过程
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
}
}
// traditional lightweight locking
// 关闭偏向,偏向锁禁用
if (!success) {
// new 无锁001
markWord displaced = lockee->mark().set_unlocked();
entry->lock()->set_displaced_header(displaced);
bool call_vm = UseHeavyMonitors;
// cas 偏向锁的状态为无锁001
if (call_vm || lockee->cas_set_mark(markWord::from_pointer(entry), displaced) != displaced) {
// cas失败
// 是否是重入锁
// Is it simple recursive case?
if (!call_vm && THREAD->is_lock_owned((address) displaced.clear_lock_bits().to_pointer())) {
entry->lock()->set_displaced_header(markWord::from_pointer(NULL));
} else {
// 其它线程持有偏向锁,执行锁撤销,轻量锁膨胀过程
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
}
}
// 获取cpu进行执行
UPDATE_PC_AND_TOS(1, -1);
goto run;
}
default: {
fatal("Unexpected message from frame manager");
}
}
轻量锁加锁执行逻辑
void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
markOop mark = obj->mark();
assert(!mark->has_bias_pattern(), "should not see bias pattern here");
// 是否是无锁001,(锁撤销是否成功)(其它线程有无持有锁)
if (mark->is_neutral()) {
// 无锁001
// Anticipate successful CAS -- the ST of the displaced mark must
// be visible <= the ST performed by the CAS.
lock->set_displaced_header(mark);
// cas 修改锁对象mark word指向lock record
if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) {
// 成功修改锁对象mark word指向lock record
TEVENT (slow_enter: release stacklock) ;
// 返回,获取cpu执行
return ;
}
// Fall through to inflate() ...
} else{
// 有锁001
// 是否是重入锁
if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
assert(lock != mark->locker(), "must not re-lock the same lock");
assert(lock != (BasicLock*)obj->mark(), "don't relock with same BasicLock");
lock->set_displaced_header(NULL);
return;
}
#if 0
// The following optimization isn't particularly useful.
if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) {
lock->set_displaced_header (NULL) ;
return ;
}
#endif
// The object header will never be displaced to this lock,
// so it does not matter what the value is, except that it
// must be non-zero to avoid looking like a re-entrant lock,
// and must not look locked either.
lock->set_displaced_header(markOopDesc::unused_mark());
// 锁膨胀成重量锁
ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);
}
}
梳理的流程