1.wait/wait(timeout)
wait有三个重载的方法:但是最终都是调用native的wait(timeout)方法,那我们来看看这个方法在jvm中具体做了些什么
(图1-1)
(图1-2)
java中的object.wait方法对应c++中jvm.cpp的JVM_MonitorWait方法(图1-3),点进去看看:
1. 在JVM_MonitorWait方法里面最后调用了ObjectSynchronizer的wait方法(图1-4),继续继续,
2. 在接下来方法中(图1-5),先检查此线程的中断标记是否为true,如果是则抛出线程中断异常,接着把当前线程包装为一个ObjectWaiter节点,调用AddWaiter方法 (图1-6);
3. 在AddWaiter方法中很明显是链表操作(图1-6),将ObjectWaiter节点放入waitSet线程等待集合(双向循环链表);
4. 接着(图1-7),AddWaiter方法执行完之后调用exit方法释放锁(synchronized锁);
5. 然后(图1-8)根据传入的时间判断,直接调用操作系统park/park(timeout)函数挂起,此时线程会卡在这里;
6. 线程被唤醒之后(图1-9),线程继续执行,最后会根据之前的WasNotified参数判断是notify还是interrupt唤醒的线程,如果是interrupt唤醒的,则抛出线程中断异常;至此,wait方法结束。
(图1-3)
(图1-4)
(图1-5)
(图1-6)
(图1-7)
(图1-8)
(图1-9)
总结:
wait(timeout): 实际执行的是park(timeout),到了时间之后自动唤醒。
wait:在c源码中,将当前线程封装为一个ObjectWait节点,然后加入到一个叫做waitSet的环形双向链表(等待队列),ObjectWaiter将插入waitSet尾部,然后执行exit退出锁,最后线程执行park挂起;线程唤醒后,根据唤醒的方式,判断中断标识,抛出线程中断异常。
最后的问题:
1.文章中提到的interrupt唤醒的线程是什么鬼?interrupt不是中断线程吗?
2. notify真的能唤醒线程吗?
3.exit方法(释放锁)到底做了些什么?
4.waitSet线程等待队列(双线程循环链表)具体干什么?
5.线程何时被唤醒?
6.线程的其他方法?
这些问题将在后续文章中解答...感谢各位的阅读。