Object.wait和Object.notify实现
Object作为java中所有对象的基类,其存在的价值不言而喻,其中wait()和notify()方法的实现多线程协作提供了保证。
ObjectMonitor
在HotSpot虚拟机中,monitor采用ObjectMonitor实现。

ObjectMonitor对象中有两个队列:_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表;_owner指向获得ObjectMonitor对象的线程。

_WaitSet:处于wait状态的线程,会被加入到wait set;_EntryList:处于等待锁block状态的线程,会被加入到entry list;
ObjectWaiter
ObjectWaiter对象是双向链表结构,保存了_thread(当前线程)以及当前的状态TState等数据, 每个等待锁的线程都会被封装成ObjectWaiter对象。

wait方法实现
lock.wait()方法最终通过ObjectMonitor的void wait(jlong millis, bool interruptable, TRAPS);
实现过程:
- 1、将当前线程封装成
ObjectWaiter对象node; - 2、通过
ObjectMonitor::AddWaiter方法将node添加到_WaitSet列表中; - 3、通过
ObjectMonitor::exit方法释放当前的ObjectMonitor对象,这样其它竞争线程就可以获取该ObjectMonitor对象。 - 4、最终底层的
park()方法会挂起线程;
notify方法实现
lock.notify()方法最终通过ObjectMonitor的void notify(TRAPS)实现。
- 1、如果当前
_WaitSet为空,即没有正在等待的线程,则直接返回; - 2、通过
ObjectMonitor::DequeueWaiter方法,获取_WaitSet列表中的第一个ObjectWaiter节点,实现也很简单。这里需要注意的是,在jdk的notify()方法注释是随机唤醒一个线程,其实是第一个ObjectWaiter节点。 - 3、根据不同的策略,将取出来的
ObjectWaiter节点,加入到_EntryList或则通过Atomic::cmpxchg_ptr指令进行自旋操作cxq
notifyAll方法实现
lock.notifyAll()方法最终通过ObjectMonitor的void notifyAll(TRAPS)实现:
通过for循环取出_WaitSet的ObjectWaiter节点,并根据不同策略,加入到_EntryList或则进行自旋操作。