Object.wait和monitor源码
作者:互联网
面试被问到了wait和sleep区别,才知道这种使用场景完全不同的东西还能问区别…不过,确实没看过这俩的源码,来看一下。
解释器映射op的过程
我这里看的是art源码,而非jvm源码。本人对bytecode到真正执行代码的映射暂无认知,经高人指点是所有的解释器实现是在interpreter目录中。
入口是interpreter.cpp#EnterInterpreterFromInvoke -> Execute -> ExecuteSwitch -> interpreter_switch_impl.h#ExecuteSwitchImpl -> ExecuteSwitchImplAsm 断到汇编里了…后面部分是猜的-> interpreter_switch_impl-inl.h#OP_NAME(见list)
Monitor enter和exit
这个是基础,因为wait必须在monitor保护下。monitor相关的背景知识 。
monitor#enter
interpreter_switch_impl-inl.h#MONITOR_ENTER -> 这里会把寄存器里的对象拿出来,传给interpreter_common.h#DoMonitorEnter -> object-inl.h#MonitorEnter -> monitor.cc#MonitorEnter
- 获取锁字段,Object#GetLockWord,锁字段是在对象头中的32bit数据
- 根据锁类型来进行下一步操作
- 无锁,直接锁上thin lock
- thin lock,检查thin lock owner(thread id)是否与当前线程id相同。
- 如果相同,获取thin lock个数,未超阈值会更新lock word,如果更新失败会有个自旋;超过阈值会InflateThinLocked。(获取的时候都会调用CheckReadBarrierState,没看懂干嘛了。)
- 如果不同,会自旋尝试获取thin lock阈值次。如果超过自旋阈值会先yeild,再等待调度;如果未超会InflateThinLocked。
- fat lock,因为有多线程,所以先atomic_thread_fence保护上。然后LockWord#FatLockMonitor(返回一个Monitor对象)-> Monitor#(Try)Lock
- TryLock,基本上就是操作c++的mutex了,如果成功就直接return了
- 大概率当前线程不是Monitor的owner
- 把自己设置到线程的SetMonitorEnterObject上
- 靠mutex获取锁,释放cpu
- 锁获取成功,修改owner
monitor#InflateThinLocked
- 看起来是利用TheadList来做等待的 // TODO
- 利用MonitorPool构造一个Monitor
- Monitor#Install,替换对象头
- 加到MonitorList中。看起来只是为了不释放?
Object#wait
仍然是走到了Monitor#wait,整体就是一个线程等待队列,类似于AQS,核心是AppendToWaitSet和RemoveFromWaitSet。
标签:Monitor,lock,Object,源码,interpreter,wait,monitor 来源: https://blog.csdn.net/pouloghost/article/details/121787718