现在不太清楚,

    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

jvm源码解读--16 锁_开头的更多相关文章

  1. jvm源码解读--16 cas 用法解析

    CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...

  2. JVM 源码解读之 CMS 何时会进行 Full GC

    t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...

  3. synchronized的jvm源码分析聊锁的意义

    上篇写完了ReentrantLock源码实现,从我们的角度分析设计锁,在对比大神的实现,顺道拍了一波道哥的马屁,虽然他看不到,哈哈.这一篇我们来聊一聊synchronized的源码实现,并对比reen ...

  4. jvm源码解读--17 Java的wait()、notify()学习

    write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...

  5. jvm源码解读--11 ldc指令的解读

    写一个java文件 public static void main(String[] args) { String str1="abc"; String str2 ="a ...

  6. jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处

    之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...

  7. Redisson源码解读-分布式锁

    前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).Redisson有一样功能是可重入的分布式锁.本文来讨论一下这个功能的特点以及源 ...

  8. jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析

    粘贴源码 package com.test; import java.util.Random; public class Test { static int number=12; private in ...

  9. Redisson源码解读-公平锁

    前言 我在上一篇文章聊了Redisson的可重入锁,这次继续来聊聊Redisson的公平锁.下面是官方原话: 它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程.所有请 ...

随机推荐

  1. Mybatis数据连接池的配置---增删改查(以及遇见的问题)

    1.首先创建项目和各个文件,如图所示: 2.配置相关数据库连接 在jdbc.properties中加入 1 db.driver=com.mysql.jdbc.Driver 2 db.url=jdbc: ...

  2. hash表及带注释插头dp

    struct hash_map { node s[SZ+10];int e,adj[SZ+10]; inline void init(){e=0;memset(adj,0,sizeof(adj));} ...

  3. ORA-00937: not a single-group group function

    有时候查询会遇到如下错误   SCOTT@PROD> select deptno,sum(sal) from emp; select deptno,sum(sal) from emp       ...

  4. 【科普】MySQL中DDL操作背后的并发原理

    一. 简介 DQL:指数据库中的查询(select)操作. DML:指数据库中的插入(insert).更新(update).删除(delete)等行数据变更操作. DDL:指数据库中加列(add co ...

  5. 用vue ui创建的项目怎么关闭eslint校验

    在Vue Cli的控制面板找到配置-ESLint configuration,然后关闭保存时检查就可以了

  6. Tkinter 吐槽之二:Event 事件在子元素中共享

    背景 最近想简单粗暴的用 Python 写一个 GUI 的小程序.因为 Tkinter 是 Python 自带的 GUI 解决方案,为了部署方便,就直接选择了 Tkinter. 本来觉得 GUI 发展 ...

  7. Redis的Pipeline、事务和lua

    1. Pipeline 1.1 Pipeline概念 Redis客户端执行一条命令分别为如下4个过程: 1) 发送命令 2) 命令排队 3) 命令执行 4) 返回结果 其中1)+4)称为Round T ...

  8. 关于Excel中表格转Markdown格式的技巧

    背景介绍 Excel文件转Markdown格式的Table是经常会遇到的场景. Visual Studio Code插件 - Excel to Markdown table Excel to Mark ...

  9. nginx负载均衡与反向代理

    1.集群的特点 (1)高性能 (2)价格有效性 (3)可伸缩性 (4)高可用性 (5)透明性 2.负载均衡概述 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡.分 ...

  10. 升级Ubuntu 16.04 到 Ubuntu 18.04 的方法

    特别注意,在进行升级前,请做好重要数据备份工作,防止升级失败或者其他奇怪原因,导致数据丢失或损坏 sudo vim /etc/apt/sources.list 将 http://archive.ubu ...