1)從java的視角看synchronizedhtml
synchronized使用的鎖對象(monitor)存儲在java對象頭中。 monitor對象: 1)每一個java對象都擁有一個Monitor鎖(別問我爲何,虛擬機就是這樣設計的)。 2)當一個monitor被持有後,它將處於鎖定狀態。
2)從C++源碼看synchronized (參考:http://www.javashuo.com/article/p-qwevqyhu-dg.html)java
oopDesc ---> markOopDesc monitor()方法 --> ObjectMonitor 即 monitor -> monitor enter、monitor exit 1)openjdk\hotspot\src\share\vm\oops\oop.hpp下的oopDesc類是JVM對象的頂級基類,故每一個object都包含markOop。 class oopDesc { friend class VMStructs; private: volatile markOop _mark; //標記字段(Mark Word) union _metadata { Klass* _klass; //對象類型元數據的指針 narrowKlass _compressed_klass; } _metadata; // Fast access to barrier set. Must be initialized. static BarrierSet* _bs; public: markOop mark() const { return _mark; } markOop* mark_addr() const { return (markOop*) &_mark; } void set_mark(volatile markOop m) { _mark = m; } void release_set_mark(markOop m); markOop cas_set_mark(markOop new_mark, markOop old_mark); // Used only to re-initialize the mark word (e.g., of promoted // objects during a GC) -- requires a valid klass pointer void init_mark(); Klass* klass() const; Klass* klass_or_null() const volatile; Klass** klass_addr(); narrowKlass* compressed_klass_addr(); ....省略... } 2)markOopDesc繼承自oopDesc,並拓展了本身的方法monitor(),該方法返回一個ObjectMonitor*對象指針。 ObjectMonitor* monitor() const { assert(has_monitor(), "check"); // Use xor instead of &~ to provide one extra tag-bit check. return (ObjectMonitor*) (value() ^ monitor_value); // -------------- 補充 --------------------- // value()的實現: uintptr_t value() const { return (uintptr_t) this; } // // monitor_value的實現: // enum { // locked_value = 0,//00偏向鎖 // unlocked_value = 1,//01無鎖 // monitor_value = 2,//10監視器鎖,又叫重量級鎖 // marked_value = 3,//11GC標記 // biased_lock_pattern = 5 //101偏向鎖 // }; // -------------- 補充 --------------------- } 3)在HotSpot虛擬機中,採用ObjectMonitor類來實現monitor。 openjdk\hotspot\src\share\vm\runtime\objectMonitor.hpp源碼以下: ObjectMonitor() { _header = NULL;//markOop對象頭 _count = 0; _waiters = 0,//等待線程數 _recursions = 0;//重入次數 _object = NULL; _owner = NULL;//指向得到ObjectMonitor對象的線程或基礎鎖 _WaitSet = NULL;//處於wait狀態的線程,會被加入到wait set; _WaitSetLock = 0 ; _Responsible = NULL ; _succ = NULL ; _cxq = NULL ; FreeNext = NULL ; _EntryList = NULL ;//處於等待鎖block狀態的線程,會被加入到entry set; _SpinFreq = 0 ; _SpinClock = 0 ; OwnerIsThread = 0 ;// _owner is (Thread *) vs SP/BasicLock _previous_owner_tid = 0;// 監視器前一個擁有者線程的ID }