现在不太清楚,
public static void main(String[] args) { Object object=new Object(); System.out.println("before synchronized start"); synchronized (object) { int am =object.hashCode(); System.out.println("start"); synchronized (object) { int a=object.hashCode(); System.out.println("inner"); } System.out.println("end"); }
断点
//%note monitor_1 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem)) #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } Handle h_obj(thread, elem->obj()); assert(Universe::heap()->is_in_reserved_or_null(h_obj()), "must be NULL or an object"); if (UseBiasedLocking) { // Retry fast entry if bias is revoked to avoid unnecessary inflation ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK); } else { ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK); } assert(Universe::heap()->is_in_reserved_or_null(elem->obj()), "must be NULL or an object"); #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif IRT_END
这个只会在嵌套的第二个里面,搞不懂,为什么第一次不会再第一次synchronized进入
通过thread打印栈帧
(gdb) x/50xg 0x7f8c1cd976d0 0x7f8c1cd976d0: 0xffffffffdb26d002 BasicObjectLock 0x00000000f3886948 0x7f8c1cd976e0: 0x0000000000000001 0x00000000f3886948 obj 0x7f8c1cd976f0: 0x00007f8c1cd976d0 -8 0x00007f8c192357be -7 0x7f8c1cd97700: 0x00007f8c1cd97798 -6 0x00007f8c19235aa8 -5 0x7f8c1cd97710: 0x0000000000000000 -4 0x00007f8c192359c8 -3 0x7f8c1cd97720: 0x0000000000000000 -2 0x00007f8c1cd97798 -1 0x7f8c1cd97730: 0x00007f8c1cd97800 fp() 0x00007f8c05000671 0x7f8c1cd97740: 0x0000000000000000 0x0000000000000000 0x7f8c1cd97750: 0x0000000000000000 0x0000000000000000 0x7f8c1cd97760: 0x0000000000000000 0x0000000000000000 0x7f8c1cd97770: 0x0000000000000000 0x00000000f3886948 0x7f8c1cd97780: 0x0000000033909752 0x00000000f3886948 0bj 0x7f8c1cd97790: 0x00000000f3886948 obj 0x00000000f3886938 args[] 0x7f8c1cd977a0: 0x00007f8c00001fa0 -12 0x00007f8c1cd98700 -11 0x7f8c1cd977b0: 0x0000000000000000 -10 0x00007f8c1cd97b40 -9 0x7f8c1cd977c0: 0x0000000000000001 -8 0x00007f8c05000564 -7 0x7f8c1cd977d0: 0x00007f8c1cd97880 -6 0x00007f8c1cd97d28 -5 0x7f8c1cd977e0: 0x00007f8c0000000a -4 0x00007f8c192359c8 -3 0x7f8c1cd977f0: 0x00007f8c0501e2e0 -2 0x00007f8c1cd97b40 -1 0x7f8c1cd97800: 0x00007f8c1cd97a40 saved rbp 0x00007f8c1b486e2e return addr 0x7f8c1cd97810: 0x0000000000000001 param size 0x00007f8c1400b800 thread 0x7f8c1cd97820: 0x00007f8c1400b800 0x00007f8c1cd97b30 0x7f8c1cd97830: 0x00007f8c1cd97c50 0x00007f8c1cd97d20 0x7f8c1cd97840: 0x00007f8c1400b800 0x00007f8c1400c078 0x7f8c1cd97850: 0x00007f8c1400c0e8 0x00007f8c1400c108
sp头顶是是elem
(gdb) p * elem $1 = {_lock = {_displaced_header = 0xffffffffdbae1002}, _obj = 0xf3886978}
那么看下BasicObjectLock定义
class BasicObjectLock VALUE_OBJ_CLASS_SPEC { friend class VMStructs; private: BasicLock _lock; // the lock, must be double word aligned oop _obj; // object holds the lock; public: // Manipulation .... };
(gdb) p elem._lock $3 = {_displaced_header = 0xffffffffdbae1002}
那看下lock定义
class BasicLock VALUE_OBJ_CLASS_SPEC { friend class VMStructs; private: volatile markOop _displaced_header; public: markOop displaced_header() const { return _displaced_header; } void set_displaced_header(markOop header) { _displaced_header = header; } void print_on(outputStream* st) const; // move a basic lock (used during deoptimization void move_to(oop obj, BasicLock* dest); static int displaced_header_offset_in_bytes() { return offset_of(BasicLock, _displaced_header); } };
就是记录的一个markOop头
enum { locked_value = 0, //轻量级 unlocked_value = 1, //无锁 monitor_value = 2, 重量级 marked_value = 3, biased_lock_pattern = 5 偏向锁 };
那么打印一下这个oop中指示的互斥锁对象
(gdb) p * inf $43 = { static SpinCallbackFunction = 0x0, static SpinCallbackArgument = 0, _header = 0x3390975201, _object = 0xf3886978, SharingPad = {-7.4786357953083842e+240}, _owner = 0x7f24b05236e0, _previous_owner_tid = 0, _recursions = 0, OwnerIsThread = 0, _cxq = 0x0, _EntryList = 0x0, _succ = 0x0, _Responsible = 0x0, _PromptDrain = -235802127, _Spinner = -235802127, _SpinFreq = 0, _SpinClock = 0, _SpinDuration = 5000, _SpinState = -1012762419733073423, _count = 0, _waiters = 0, _WaitSet = 0x0, _WaitSetLock = 0, _QMix = -235802127, FreeNext = 0x0, StatA = -1012762419733073423, StatsB = -1012762419733073423, static _sync_ContendedLockAttempts = 0x7f24a800d8f8, static _sync_FutileWakeups = 0x7f24a800d9c8, static _sync_Parks = 0x7f24a800da88, static _sync_EmptyNotifications = 0x7f24a800db48, static _sync_Notifications = 0x7f24a800dc08, static _sync_SlowEnter = 0x7f24a800dcc8, static _sync_SlowExit = 0x7f24a800dd88, static _sync_SlowNotify = 0x7f24a800de48, static _sync_SlowNotifyAll = 0x7f24a800df08, static _sync_FailedSpins = 0x0, static _sync_SuccessfulSpins = 0x7f24a800e088, static _sync_PrivateA = 0x7f24a800e148, static _sync_PrivateB = 0x7f24a800e208, static _sync_MonInCirculation = 0x7f24a800e2c8, static _sync_MonScavenged = 0x7f24a800e388, static _sync_Inflations = 0x7f24a800d378, static _sync_Deflations = 0x7f24a800d838, static _sync_MonExtant = 0x7f24a800e448, static Knob_Verbose = 0, static Knob_SpinLimit = 5000 } (gdb) p object $44 = (oopDesc *) 0xf3886978