Repository navigation
lock basic_lock
wangkaiwu edited this page Feb 14, 2022
·
2 revisions
void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) {
markWord mark = obj->mark();
// 是否无锁
if (mark.is_neutral()) {
// lock 在线程栈上分配,此步骤是记录对象的 markword 到 lock 对象中。
lock->set_displaced_header(mark);
// 尝试将对象从无锁变为轻量锁
if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
return;
}
} else if (mark.has_locker() && current->is_lock_owned((address)mark.locker())) {
// 如果已经被轻量级锁锁定,且 markword 指向的栈地址位于本线程的栈空间
// 则相当于锁重入,此时只需要将当前栈帧的 lock 对象的 displaced_header 置为无效
lock->set_displaced_header(markWord::from_pointer(NULL));
return;
}
// 将 displaced_header 置为无效
lock->set_displaced_header(markWord::unused_mark());
while (true) {
// 膨胀为重量级锁
ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_monitor_enter);
if (monitor->enter(current)) {
return;
}
}
}ObjectMonitor* ObjectSynchronizer::inflate(Thread* current, oop object, const InflateCause cause) {
EventJavaMonitorInflate event;
for (;;) {
// 对象的 markword
const markWord mark = object->mark();
// 是否已经是重量锁了
if (mark.has_monitor()) {
ObjectMonitor* inf = mark.monitor();
// 返回 monitor 指针
return inf;
}
// markWord::INFLATING() == 0,判断是否在膨胀中
if (mark == markWord::INFLATING()) {
//TODO:
read_stable_mark(object);
continue;
}
// 是否是轻量锁
if (mark.has_locker()) {
// 创建 monitor 对象
ObjectMonitor* m = new ObjectMonitor(object);
// 修改被锁对象为膨胀中的状态
markWord cmp = object->cas_set_mark(markWord::INFLATING(), mark);
// 判断是否cas操作成功
if (cmp != mark) {
// 操作失败,重试
delete m;
continue; // Interference -- just retry
}
// 轻量锁生效时,对象 markword 中存储的是 lock record 的地址
// lock record 对应的是持有锁线程的栈空间里的一个对象
// 下面方法可以从 lock record 中取到锁对象原来的mark word
markWord dmw = mark.displaced_mark_helper();
// 在 monitor 中存储 mark word
m->set_header(dmw);
// 设置锁当前被哪个线程持有
m->set_owner_from(NULL, mark.locker());
// 由于升级为重量级锁,所以对象头存储的 mark word 需要改为 monitor 的地址
object->release_set_mark(markWord::encode(m));
// 添加到使用列表中
_in_use_list.add(m);
// 发出膨胀事件
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
}
return m;
}
// 当前已经处于重量锁中,尝试一下能否获取到锁
ObjectMonitor* m = new ObjectMonitor(object);
// 在 monitor 中记录 mark word
m->set_header(mark);
// 尝试将对象的mark word 设置为 monitor 对象的地址
if (object->cas_set_mark(markWord::encode(m), mark) != mark) {
// 修改失败,删除对象
delete m;
m = NULL;
continue;
}
// 升级为膨胀锁
_in_use_list.add(m);
// 发出膨胀事件
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
}
return m;
}
}bool ObjectMonitor::enter(JavaThread* current) {
// 尝试占有锁
void* cur = try_set_owner_from(NULL, current);
if (cur == NULL) {
// 抢占成功
return true;
}
// 判定是否锁重入
if (cur == current) {
// 记录重入次数
_recursions++;
// 锁重入
return true;
}
// TODO: 不太理解,表层意思就是比较占有锁的线程是否是当前线程
if (current->is_lock_owned((address)cur)) {
_recursions = 1;
set_owner_from_BasicLock(cur, current); // Convert from BasicLock* to Thread*.
return true;
}
// 设置当前线程的 _Stalled 为当前 monitor 的地址
current->_Stalled = intptr_t(this);
// 尝试自旋获取锁
if (TrySpin(current) > 0) {
current->_Stalled = 0;
return true;
}
add_to_contentions(1);
if (is_being_async_deflated()) {
const oop l_object = object();
if (l_object != NULL) {
install_displaced_markword_in_object(l_object);
}
current->_Stalled = 0;
add_to_contentions(-1);
return false;
}
EventJavaMonitorEnter event;
if (event.is_started()) {
event.set_monitorClass(object()->klass());
event.set_address((uintptr_t)this);
}
{
JavaThreadBlockedOnMonitorEnterState jtbmes(current, this);
current->set_current_pending_monitor(this);
OSThreadContendState osts(current->osthread());
for (;;) {
ExitOnSuspend eos(this);
{
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivs(current, eos);
EnterI(current);
current->set_current_pending_monitor(NULL);
}
if (!eos.exited()) {
break;
}
}
}
add_to_contentions(-1);
current->_Stalled = 0;
if (event.should_commit()) {
event.set_previousOwner((uintptr_t)_previous_owner_tid);
event.commit();
}
return true;
}