jvm源码解读--16 锁_开头
现在不太清楚,
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 锁_开头的更多相关文章
- jvm源码解读--16 cas 用法解析
CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...
- JVM 源码解读之 CMS 何时会进行 Full GC
t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...
- synchronized的jvm源码分析聊锁的意义
上篇写完了ReentrantLock源码实现,从我们的角度分析设计锁,在对比大神的实现,顺道拍了一波道哥的马屁,虽然他看不到,哈哈.这一篇我们来聊一聊synchronized的源码实现,并对比reen ...
- jvm源码解读--17 Java的wait()、notify()学习
write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...
- jvm源码解读--11 ldc指令的解读
写一个java文件 public static void main(String[] args) { String str1="abc"; String str2 ="a ...
- jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处
之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...
- Redisson源码解读-分布式锁
前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).Redisson有一样功能是可重入的分布式锁.本文来讨论一下这个功能的特点以及源 ...
- jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
粘贴源码 package com.test; import java.util.Random; public class Test { static int number=12; private in ...
- Redisson源码解读-公平锁
前言 我在上一篇文章聊了Redisson的可重入锁,这次继续来聊聊Redisson的公平锁.下面是官方原话: 它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程.所有请 ...
随机推荐
- 深度学习的优化器(各类 optimizer 的原理、优缺点及数学推导)
深度学习优化器 深度学习中的优化器均采用了梯度下降的方式进行优化,所谓炼丹我觉得优化器可以当作灶,它控制着火量的大小.形式与时间等. 初级的优化器 首先我们来一下看最初级的灶台(100 - 1000 ...
- 流程自动化RPA,Power Automate Desktop系列 - 批量备份Git仓库做好灾备
一.背景 打个比如,你在Github上的代码库需要批量的定时备案到本地的Gitlab上,以便Github不能访问时,可以继续编写,这时候我们可以基于Power Automate Desktop来实现一 ...
- hive学习笔记之六:HiveQL基础
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 信奥赛一本通1573:分离与合体C++分离与合体
题目链接 #include<cstdio> #include<algorithm> using namespace std; int dp[305][305]={},jojo[ ...
- @EnableDiscoveryClient与Nacos自动注册
前一阵看到有篇博客说cloud从Edgware版本开始,可以不加@EnableDiscoveryClient注解,只要配置好注册中心的相关配置即可自动开启服务注册功能,比较好奇其中的原理,研究了一番特 ...
- 使用CI/CD工具Github Action发布jar到Maven中央仓库
之前发布开源项目Payment Spring Boot到Maven中央仓库我都是手动执行mvn deploy,在CI/CD大行其道的今天使用这种方式有点"原始".于是我一直在寻求一 ...
- AcWing 106. 动态中位数
依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. #include<bits/stdc++.h> using namespace std; pri ...
- Java:HttpPost 传输Json数据过长使用HttpServletRequest解析
直接上代码 /** * 测试生成json数据 */ @Test public void synYxGoodsInfoTest() { try { String url = "http://1 ...
- Docker:docker安装部署jenkins
Docker安装步骤请转到:https://www.cnblogs.com/nhdlb/p/11262527.html 查看docker的jenkins镜像版本 #查看jenkins版本命令 dock ...
- linux 操作目录
脚本 获取一个目录下各子目录中的文件个数 #!/bin/sh find /tmp/homework -maxdepth 1 -type d | while read dir; do count=$(f ...