先介紹2個對象:
1. ObjectMonitor 對象 主要用來監視創立的Object
在synchronizer.cpp 裏定義了,ObjectMonitor 的對象,我們來看ObjectMonitor的對象的結構體
- ObjectMonitor::ObjectMonitor() {
- _header = NULL;
- _count = 0;
- _waiters = 0,
- _recursions = 0;
- _object = NULL;
- _owner = NULL;
- _WaitSet = NULL;
- _WaitSetLock = 0 ;
- _Responsible = NULL ;
- _succ = NULL ;
- _cxq = NULL ;
- FreeNext = NULL ;
- _EntryList = NULL ;
- _SpinFreq = 0 ;
- _SpinClock = 0 ;
- OwnerIsThread = 0 ;
- }
每個object的對象裏 markOop->monitor() 裏可以保存ObjectMonitor的對象。
建立ObjectMonitor的算法:
如果不存在,可以向Thread 的ObjectMonitor 的對象列表中Allocate free objectMonitor 對象。
每個線程都有ObjectMonitor 的free和used的objectMonitor對象列表,如果沒有free objectMonitor對象列表,將向global 中ListLock Allocate爲了提高效率。
2. ObjectWaiter 對象
ObjectWaiter 對象
- class ObjectWaiter : public StackObj {
- public:
- enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
- enum Sorted { PREPEND, APPEND, SORTED } ;
- ObjectWaiter * volatile _next;
- ObjectWaiter * volatile _prev;
- Thread* _thread;
- ParkEvent * _event;
- volatile int _notified ;
- volatile TStates TState ;
- Sorted _Sorted ; // List placement disposition
- bool _active ; // Contention monitoring is enabled
- public:
- ObjectWaiter(Thread* thread) {
- _next = NULL;
- _prev = NULL;
- _notified = 0;
- TState = TS_RUN ;
- _thread = thread;
- _event = thread->_ParkEvent ;
- _active = false;
- assert (_event != NULL, "invariant") ;
- }
- void wait_reenter_begin(ObjectMonitor *mon) {
- JavaThread *jt = (JavaThread *)this->_thread;
- _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon);
- }
- void wait_reenter_end(ObjectMonitor *mon) {
- JavaThread *jt = (JavaThread *)this->_thread;
- JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active);
- }
- };
ObjectWaiter 對象裏存放thread(線程對象) 和 ParkEvent(線程的unpark), 每一個等待鎖的線程都會有一個ObjectWaiter對象.
而objectwaiter是個雙向鏈表結構的對象。
我們可以看到在ObjectMonitor對象裏有2個隊列成員_WaitSet 和 _EntryList 存放的就是ObjectWaiter
_WaitSet:
主要存放所有wait的線程的對象,也就是說如果有線程處於wait狀態,將被掛入這個隊列
_EntryList:
所有在等待獲取鎖的線程的對象,也就是說如果有線程處於等待獲取鎖的狀態的時候,將被掛入這個隊列。
Wait 方法實現:
ObjectSynchronizer::wait方法
通過object的對象中找到ObjectMonitor對象
調用方法
void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS)
通過ObjectMonitor::AddWaiter調用把新建立的ObjectWaiter對象放入到 _WaitSet 的隊列的末尾中
然後在ObjectMonitor::exit釋放鎖,接着 thread_ParkEvent->park 也就是wait
Notify方法的實現:
ObjectSynchronizer::notify方法
調用ObjectSynchronizer::inflate
object的對象中找到ObjectMonitor對象
然後調用方法ObjectMonitor::notify
調用ObjectMonitor::DequeueWaiter 摘除第一個ObjectWaiter對象從_WaitSet 的隊列中
並把這個ObjectWaiter對象放入_EntryList中,_EntryList 存放的是ObjectWaiter的對象列表,列表的大小就是那些所有在等待這個對象鎖的線程數。
注意這裏並沒有調用ObjectMonitor::exit釋放鎖
NotifyALL和Notify 的區別就是
通過遍歷調用ObjectMonitor::DequeueWaiter,把所有的_WaitSet的隊列中的ObjectWaiter對象放入到_EntryList中
關於放入到_EntryList的策略大概有4中Policy,其中還涉及到一個_cxq的隊列,先不具體介紹了
notify, 和notifyAll 都沒有釋放對象的鎖,而是在Synchronizer同步塊結束的時候釋放
如何釋放鎖
調用ObjectMonitor::exit
從_EntryList裏找到一個ObjectWaiter,因爲ObjectWaiter裏有線程的_event ParkEvent,調用unpark() 通知ObjectWaite裏的線程運行(拿到鎖),具體實現在ObjectMonitor::ExitEpilog方法裏