void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
//获取对象的markword
markOop mark = obj->mark();
assert(!mark->has_bias_pattern(), "should not see bias pattern here");
//如果当前对象没有锁
if (mark->is_neutral()) {
//复制markword到栈
lock->set_displaced_header(mark);
//如果CAS更新指向栈中的指针成功则释放栈锁,并返回
if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) {
TEVENT (slow_enter: release stacklock) ;
return ;
}
} else
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;
}
lock->set_displaced_header(markOopDesc::unused_mark());
//锁膨胀
ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); //enter方法很关键
}
重量级锁
ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {
assert (Universe::verify_in_progress() ||
!SafepointSynchronize::is_at_safepoint(), "invariant") ;
//自旋
for (;;) {
const markOop mark = object->mark() ;
assert (!mark->has_bias_pattern(), "invariant") ;
// 如果已经膨胀为重量级锁则直接返回
if (mark->has_monitor()) {
//获取对象的监视器锁
ObjectMonitor * inf = mark->monitor() ;
assert (inf->header()->is_neutral(), "invariant");
assert (inf->object() == object, "invariant") ;
assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
return inf ;
}
//膨胀等待,其它线程正在从轻量级锁膨胀到重量级锁
if (mark == markOopDesc::INFLATING()) {
TEVENT (Inflate: spin while INFLATING) ;
ReadStableMark(object) ;
continue ;
}
//存在轻量级锁
if (mark->has_locker()) {
//获取可用监视器锁
ObjectMonitor * m = omAlloc (Self) ;
//初始化监视器锁
m->Recycle();
m->_Responsible = NULL ;
m->OwnerIsThread = 0 ;
m->_recursions = 0 ;
m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // Consider: maintain by type/class
//CAS更新状态为膨胀中
markOop cmp = (markOop) Atomic::cmpxchg_ptr (markOopDesc::INFLATING(), object->mark_addr(), mark) ;
//CAS更新失败
if (cmp != mark) {
omRelease (Self, m, true) ;
continue ; // Interference -- just retry
}
//已经成功更新了markword状态为膨胀中,它是锁状态更新为0的唯一途径,只有成功更新状态的单线程可以进行锁膨胀。
//获取栈中的markword
markOop dmw = mark->displaced_mark_helper() ;
assert (dmw->is_neutral(), "invariant") ;
//将监视器字段设置为适当的值
m->set_header(dmw) ;
//设置拥有锁的线程
m->set_owner(mark->locker());
//设置监视器的对象
m->set_object(object);
guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
object->release_set_mark(markOopDesc::encode(m));
if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
TEVENT(Inflate: overwrite stacklock) ;
if (TraceMonitorInflation) {
if (object->is_instance()) {
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
return m ;
}
// 无锁场景
assert (mark->is_neutral(), "invariant");
//分配一个有效对象监视器
ObjectMonitor * m = omAlloc (Self) ;
//重置监视器
m->Recycle();
m->set_header(mark);
m->set_owner(NULL);
m->set_object(object);
m->OwnerIsThread = 1 ;
m->_recursions = 0 ;
m->_Responsible = NULL ;
m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ;
if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) {
m->set_object (NULL) ;
m->set_owner (NULL) ;
m->OwnerIsThread = 0 ;
m->Recycle() ;
omRelease (Self, m, true) ;
m = NULL ;
continue ;
}
if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
TEVENT(Inflate: overwrite neutral) ;
if (TraceMonitorInflation) {
if (object->is_instance()) {
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
return m ;
}
}
Thread * const Self = THREAD ;
void * cur ;
//如果当前监视器锁没有被占用,通过CAS将owner更新为当前线程
cur = Atomic::cmpxchg_ptr (Self, &_owner, NULL) ;
//如果更新成功则返回
if (cur == NULL) {
// Either ASSERT _recursions == 0 or explicitly set _recursions = 0.
assert (_recursions == 0 , "invariant") ;
assert (_owner == Self, "invariant") ;
// CONSIDER: set or assert OwnerIsThread == 1
return ;
}
//如果重入,则_recursions自增
if (cur == Self) {
_recursions ++ ;
return ;
}
//获取监视器锁成功,将_recursions设置为1,_owner设置为当前线程
if (Self->is_lock_owned ((address)cur)) {
assert (_recursions == 0, "internal state error");
_recursions = 1 ;
_owner = Self ;
OwnerIsThread = 1 ;
return ;
}
//创建ObjectWaiter
ObjectWaiter node(Self) ;
Self->_ParkEvent->reset() ;
node._prev = (ObjectWaiter *) 0xBAD ;
node.TState = ObjectWaiter::TS_CXQ ;
//将当前线程添加到_cxq加入到对头
ObjectWaiter * nxt ;
for (;;) {
node._next = nxt = _cxq ;
if (Atomic::cmpxchg_ptr (&node, &_cxq, nxt) == nxt) break ;
//再次尝试获取锁
if (TryLock (Self) > 0) {
return ;
}
}
if ((SyncFlags & 16) == 0 && nxt == NULL && _EntryList == NULL) {
Atomic::cmpxchg_ptr (Self, &_Responsible, NULL) ;
}
TEVENT (Inflated enter - Contention) ;
int nWakeups = 0 ;
int RecheckInterval = 1 ;
for (;;) {
//尝试获取锁
if (TryLock (Self) > 0) break ;
assert (_owner != Self, "invariant") ;
if ((SyncFlags & 2) && _Responsible == NULL) {
Atomic::cmpxchg_ptr (Self, &_Responsible, NULL) ;
}
// 如果指定时间则挂起一段时间
if (_Responsible == Self || (SyncFlags & 1)) {
TEVENT (Inflated enter - park TIMED) ;
Self->_ParkEvent->park ((jlong) RecheckInterval) ;
// Increase the RecheckInterval, but clamp the value.
RecheckInterval *= 8 ;
if (RecheckInterval > 1000) RecheckInterval = 1000 ;
} else {//否则只能等待其它事件唤醒
TEVENT (Inflated enter - park UNTIMED) ;
Self->_ParkEvent->park() ;
}
//线程唤醒后再次尝试获取锁,如果查工获取锁结束阻塞
if (TryLock(Self) > 0) break ;
ObjectMonitor的注释:
The ObjectMonitor class implements the heavyweight version of a
JavaMonitor. The lightweight BasicLock/stack lock version has been
inflated into an ObjectMonitor. This inflation is typically due to
contention or use of Object.wait().
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者张伟授权发布。