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 }