Java的wait和notify学习三部曲之一:JVM源码分析,保洁阿姨看完都会了

  1. 线程C启动后,由于此时线程B持有锁,那么线程C此时在干啥?

  2. 线程B在notify()的时候做了什么?

  3. 线程B释放锁的时候做了什么?

源码中最重要的注释信息

在源码中有段注释堪称是整篇文章最重要的说明,请大家始终记住这段信息,处处都用得上:

ObjectWaiter对象存在于WaitSet、EntryList、cxq等集合中,或者正在这些集合中移动

原文如下:

640?wx_fmt=png

请务必记住这三个集合:WaitSet、EntryList、cxq

好了,接下来看源码分析问题吧:

线程A在wait()的时候做了什么

打开hotspot/src/share/vm/runtime/objectMonitor.cpp,看ObjectMonitor::wait方法:

640?wx_fmt=png

如上图所示,有两处代码值得我们注意:

  1. 绿框中将当前线程包装成ObjectWaiter对象,并且状态为TS_WAIT,这里对应的是jstack看到的线程状态WAITING;

  2. 红框中调用了AddWaiter方法,跟进去看下:

640?wx_fmt=png

这个ObjectWaiter对象被放入了WaitSet中,WaitSet是个环形双向链表(circular doubly linked list)

回到ObjectMonitor::wait方法接着往下看,会发现关键代码如下图,当前线程通过park()方法开始挂起(suspend):

640?wx_fmt=png

至此,我们把wait()方法要做的事情就理清了:

  1. 包装成ObjectWaiter对象,状态为TS_WAIT;

  2. ObjectWaiter对象被放入_WaitSet中;

  3. 当前线程挂起;

线程B持有锁的时候线程C在干啥

此时的线程C无法进入synchronized{}代码块,用jstack看应该是BLOCKED状态,如下图:

640?wx_fmt=png

我们看看monitorenter指令对应的源码吧,位置:openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp

IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))

#ifdef ASSERT

thread->last_

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值