作者cpp水平有限,所以阅读源码不会很深入
jdk版本: jdk18-27
该版本已删除偏向级锁流程,在jdk22中轻量级锁也删除,变为fast_lock,还引入了lock_stack
源码目录: hotspot/share/runtime/synchornized
加锁流程
//BasicLock 轻量级锁
void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) {
if (obj->klass()->is_value_based()) {
handle_sync_on_value_based_class(obj, current);
}
if (!useHeavyMonitors()) { //是否只使用重量级锁(可通过jvm参数控制)
markWord mark = obj->mark(); //拿到《要加锁的对象》的Markword
if (mark.is_neutral()) { //判断是否处于无锁状态(根据后两位标志位判断)
lock->set_displaced_header(mark); //将markword放到轻量级锁中(解锁时从里面取出,还原markword)
//from_pointer(lock) 获取轻量级锁的地址指针
//cas_set_mark() 将轻量级锁的地址指针放入《加锁的对象》的markword中
//判断是否cas成功
if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
//如果无竞争,设置成功,返回
return;
}
//获取失败
// Fall through to inflate() ...
} else if (mark.has_locker() && //如果已经加轻量级锁了 并且当前线程是锁的持有者,走锁重入流程
current->is_lock_owned((address)mark.locker())) {
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)); //锁重入时,锁对象不需要储存原始的markword信息,只放入一个空地址指针
return; //锁重入加锁流程结束
}
lock->set_displaced_header(markWord::unused_mark()); //设置没有使用的状态 不重要
} else if (VerifyHeavyMonitors) {
guarantee(!obj->mark().has_locker(), "must not be stack-locked");
}
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 (;;) {
const markWord mark = object->mark_acquire(); //获取《加锁的对象》的markword
// 几种膨胀状态,重要
// The mark can be in one of the following states:
// * Inflated - just return 膨胀完成
// * Stack-locked - coerce it to inflated 从轻量级锁开始膨胀
// * INFLATING - busy wait for conversion to complete 膨胀中
// * Neutral - aggressively inflate the object. 从无锁状态开始膨胀
// CASE: inflated
if (mark.has_monitor()) { //判断是否膨胀完毕(检查锁标志位即可)
ObjectMonitor* inf = mark.monitor();
markWord dmw = inf->header();
assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT, dmw.value());
return inf; //返回重量级锁对象
}
if (mark == markWord::INFLATING()) { //膨胀中 (线程发生竞争时,保证仅有一个线程膨胀成功)
read_stable_mark(object); //等待一会,等膨胀的那个线程膨胀完
continue;
}
LogStreamHandle(Trace, monitorinflation) lsh;
//从轻量级锁开始膨胀为重量级锁
if (mark.has_locker()) { //是否为轻量级锁 如果是则发生竞争 准备膨胀
ObjectMonitor* m = new ObjectMonitor(object);//创建一个重量级锁对象
//仅有一个线程能成功,成功的线程执行具体的膨胀流程;失败的线程循环等待
//markword信息还会有一些中间态,比如膨胀中的信息也会放入markword
markWord cmp = object->cas_set_mark(markWord::INFLATING(), mark); //将markword信息设置为膨胀中
if (cmp != mark) { //cas失败(膨胀失败,发生竞争且没抢过)
delete m; //删除重量级锁对象
continue; // Interference -- just retry
}
markWord dmw = mark.displaced_mark_helper(); //获取原始markword,准备存入重量级锁
assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT, dmw.value());
m->set_header(dmw); //原始markword存入重量级锁
m->set_owner_from(NULL, mark.locker()); //设置重量级锁持锁线程,设置的是轻量级锁的持锁线程!
guarantee(object->mark() == markWord::INFLATING(), "invariant");
object->release_set_mark(markWord::encode(m)); //《加锁的对象》后两位改成02,设置为存放重量级锁的地址指针
_in_use_list.add(m);
OM_PERFDATA_OP(Inflations, inc());
if (log_is_enabled(Trace, monitorinflation)) {
ResourceMark rm(current);
lsh.print_cr("inflate(has_locker): object=" INTPTR_FORMAT ", mark="
INTPTR_FORMAT ", type='%s'", p2i(object),
object->mark().value(), object->klass()->external_name());
}
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
}
return m; //膨胀结束,返回重量级锁
}
//从无锁状态开始膨胀
assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());//检查是否无锁
ObjectMonitor* m = new ObjectMonitor(object); //创建重量级锁
m->set_header(mark); //直接将原始markword值放入重量级锁中(因为对象是无锁状态,markword是原始的)
//将《加锁的对象》markword中设置重量级锁的地址
if (object->cas_set_mark(markWord::encode(m), mark) != mark) {
delete m; //加锁失败 删除重量级锁
m = NULL;
continue;
}
_in_use_list.add(m);
OM_PERFDATA_OP(Inflations, inc());
if (log_is_enabled(Trace, monitorinflation)) {
ResourceMark rm(current);
lsh.print_cr("inflate(neutral): object=" INTPTR_FORMAT ", mark="
INTPTR_FORMAT ", type='%s'", p2i(object),
object->mark().value(), object->klass()->external_name());
}
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
}
return m; //返回Moniter对象
}
}
释放流程
//加锁的对象 锁对象(锁本身) 操作的线程
void ObjectSynchronizer::exit(oop object, BasicLock* lock, JavaThread* current) {
if (!useHeavyMonitors()) {
markWord mark = object->mark(); //拿到《加锁的对象》的markWord
markWord dhw = lock->displaced_header(); //获取《锁对象》的对象头信息,如果发生锁重入拿的空header
if (dhw.value() == 0) { //锁重入解锁,正常情况下return 解锁成功
#ifndef PRODUCT
if (mark != markWord::INFLATING()) {
assert(!mark.is_neutral(), "invariant");
assert(!mark.has_locker() ||
current->is_lock_owned((address)mark.locker()), "invariant");
if (mark.has_monitor()) {
ObjectMonitor* m = mark.monitor();
assert(m->object()->mark() == mark, "invariant");
assert(m->is_entered(current), "invariant");
}
}
#endif
return;
}
// mark是《加锁的对象》的markword from_pointer(lock)获取的是《锁对象》的指针
// 如果相同,进入最外层轻量级锁解锁流程
if (mark == markWord::from_pointer(lock)) {
assert(dhw.is_neutral(), "invariant");
//还原《加锁的对象》的markword,完成轻量级锁解锁
//dhw作为《锁对象》,他的对象中存储的是《加锁的对象》的原始markword
if (object->cas_set_mark(dhw, mark) == mark) {
return;
}
}
} else if (VerifyHeavyMonitors) {
//重量级锁
guarantee(!object->mark().has_locker(), "must not be stack-locked");
}
//轻量级锁解锁失败,膨胀为重量级锁
ObjectMonitor* monitor = inflate(current, object, inflate_cause_vm_internal);
//再进入重量级锁解锁流程
monitor->exit(current);
}